decrypt_cookies/browser/
chromium.rs

1use std::path::PathBuf;
2
3use super::CACHE_PATH;
4
5pub trait ChromiumPath {
6    /// Suffix for browser data path
7    const BASE: &'static str;
8    /// Browser name for [`std::fmt::Display`]
9    const NAME: &'static str;
10    #[cfg(not(target_os = "windows"))]
11    /// Suffix for cookies data path (sqlite3 database)
12    const COOKIES: &str = "Default/Cookies";
13    #[cfg(target_os = "windows")]
14    /// Suffix for cookies data path (sqlite3 database)
15    const COOKIES: &str = r"Default\Network\Cookies";
16    /// Suffix for login data path (sqlite3 database)
17    const LOGIN_DATA: &str = "Default/Login Data";
18    /// Another login data (sqlite3)
19    const LOGIN_DATA_FOR_ACCOUNT: &str = "Default/Login Data For Account";
20    #[cfg(target_os = "windows")]
21    /// Suffix for decryption key path (json)
22    const KEY: &str = "Local State";
23    #[cfg(not(target_os = "windows"))]
24    /// Safe keyring Storage name
25    const SAFE_STORAGE: &str;
26    #[cfg(target_os = "macos")]
27    /// Safe keyring name
28    const SAFE_NAME: &str;
29
30    #[cfg(target_os = "windows")]
31    /// Decryption key path (json)
32    fn key(mut base: PathBuf) -> PathBuf {
33        push_exact!(base, Self::KEY);
34
35        base
36    }
37    #[cfg(target_os = "windows")]
38    /// Copy the decryption key file to a location to avoid conflicts with the browser over access to it.
39    fn key_temp() -> Option<PathBuf> {
40        push_temp!(cache, Self::KEY);
41
42        cache.into()
43    }
44
45    /// Cookies path (sqlite3 database)
46    fn cookies(mut base: PathBuf) -> PathBuf {
47        push_exact!(base, Self::COOKIES);
48
49        base
50    }
51    /// Copy the cookies file to a location to avoid conflicts with the browser over access to it.
52    fn cookies_temp() -> Option<PathBuf> {
53        push_temp!(cache, Self::COOKIES);
54
55        cache.into()
56    }
57
58    /// Login data file (sqlite3 database)
59    fn login_data(mut base: PathBuf) -> PathBuf {
60        push_exact!(base, Self::LOGIN_DATA);
61        base
62    }
63    /// Copy the Login data file to a location to avoid conflicts with the browser over access to it.
64    fn login_data_temp() -> Option<PathBuf> {
65        push_temp!(cache, Self::LOGIN_DATA);
66
67        cache.into()
68    }
69
70    /// Login data file (sqlite3 database)
71    fn login_data_for_account(mut base: PathBuf) -> PathBuf {
72        push_exact!(base, Self::LOGIN_DATA_FOR_ACCOUNT);
73        base
74    }
75    /// Copy the Login data file to a location to avoid conflicts with the browser over access to it.
76    fn login_data_for_account_temp() -> Option<PathBuf> {
77        push_temp!(cache, Self::LOGIN_DATA_FOR_ACCOUNT);
78
79        cache.into()
80    }
81}
82
83/// Register a Chromium based browser info
84///
85/// When linkme feature is enabled, the macro requires the `linkme` crate.
86///
87/// It accept
88/// - `platform`
89/// - `browser`: Generate a struct
90/// - `base: <path>`: A browser all data location relative to home dir.
91/// - `cookies: <path>`, `login_data: <path>`, `login_data_fa: <path>`: Relative to base dir. (optional)
92/// - `key: <path>`: Relative to profile dir. Require on windows.
93/// - `safe_name: <name>`: Require on linux and macos
94///
95/// # Example:
96///
97/// ```rust, no_run
98/// chromium!(
99///     "linux",
100///     Chrome,
101///     base: ".config/google-chrome",
102///     cookies: "Default/Cookies",
103///     login_data: "Default/Login Data",
104///     login_data_fa: "Default/Login Data For Account",
105///     safe_name: "Chrome",
106/// );
107/// chromium!(
108///     "windows",
109///     Chrome,
110///     base: r"AppData\Local\Google\Chrome\User Data",
111///     cookies: r"Default\Network\Cookies",
112///     login_data: r"Default\Login Data",
113///     login_data_fa: r"Default\Login Data For Account",
114///     key: "Local State",
115/// );
116/// // or omit use default value
117/// chromium!("linux", Chrome, base: ".config/google-chrome", safe_name: "Chrome");
118/// chromium!("macos", Chrome, base: "Library/Application Support/Google/Chrome", safe_name: "Chrome");
119/// chromium!("windows", Chrome, base: r"AppData\Local\Google\Chrome\User Data");
120/// ```
121#[macro_export]
122macro_rules! chromium {
123    (
124        $platform:literal,
125        $browser:ident,
126        base: $base:literal
127        $(, cookies: $cookies:literal)?
128        $(, login_data: $login_data:literal)?
129        $(, login_data_fa: $login_data_fa:literal)?
130        $(, key: $key:literal)?
131        $(, safe_name: $safe_name:literal)?
132    ) => {
133        #[cfg(feature = "linkme")]
134        $crate::pastey::paste! {
135            #[cfg(target_os = $platform)]
136            #[linkme::distributed_slice($crate::browser::BROWSERS)]
137            static [<$browser:upper _NAME>]: &str = stringify!($browser);
138        }
139
140        #[cfg(target_os = $platform)]
141        #[derive(Clone, Copy)]
142        #[derive(Debug)]
143        #[derive(Default)]
144        #[derive(PartialEq, Eq, PartialOrd, Ord)]
145        #[expect(clippy::exhaustive_structs, reason = "unit struct")]
146        pub struct $browser;
147
148        #[cfg(target_os = $platform)]
149        impl ChromiumPath for $browser {
150            const BASE: &'static str = $base;
151            const NAME: &'static str = stringify!($browser);
152            $(const COOKIES: &str = $cookies;)?
153            $(const LOGIN_DATA: &str = $login_data;)?
154            $(const LOGIN_DATA_FOR_ACCOUNT: &str = $login_data_fa;)?
155            $(const KEY: &str = $key;)?
156            $(
157                const SAFE_STORAGE: &str = concat!($safe_name, " Safe Storage");
158                #[cfg(target_os = "macos")]
159                const SAFE_NAME: &str = $safe_name;
160            )?
161        }
162
163        #[cfg(target_os = $platform)]
164        impl std::fmt::Display for $browser {
165            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166                f.write_str(Self::NAME)
167            }
168        }
169    };
170}
171
172chromium!("linux", Chrome  , base: ".config/google-chrome"              , safe_name: "Chrome"        );
173chromium!("linux", Edge    , base: ".config/microsoft-edge"             , safe_name: "Microsoft Edge");
174chromium!("linux", Chromium, base: ".config/chromium"                   , safe_name: "Chromium"      );
175chromium!("linux", Brave   , base: ".config/BraveSoftware/Brave-Browser", safe_name: "Brave"         );
176chromium!("linux", Vivaldi , base: ".config/vivaldi"                    , safe_name: "Vivaldi"       );
177chromium!("linux", Opera   , base: ".config/opera"                      , safe_name: "Opera"         );
178chromium!("linux", Yandex  , base: ".config/yandex-browser"             , login_data: "Default/Ya Passman Data", safe_name: "Yandex");
179
180macro_rules! cache_it {
181    ($($browser:ident,)*) => {
182        #[cfg(target_os = "linux")]
183        pub fn need_safe_storage(lab: &str) -> bool {
184            matches!(
185                lab,
186                $(| $browser::SAFE_STORAGE)*
187            )
188        }
189    };
190}
191cache_it!(Chrome, Edge, Chromium, Brave, Vivaldi, Opera, Yandex,);
192
193chromium!("macos", Chrome  , base: "Library/Application Support/Google/Chrome"              , safe_name: "Chrome"        );
194chromium!("macos", Edge    , base: "Library/Application Support/Microsoft Edge"             , safe_name: "Microsoft Edge");
195chromium!("macos", Chromium, base: "Library/Application Support/Chromium"                   , safe_name: "Chromium"      );
196chromium!("macos", Brave   , base: "Library/Application Support/BraveSoftware/Brave-Browser", safe_name: "Brave"         );
197chromium!("macos", Vivaldi , base: "Library/Application Support/Vivaldi"                    , safe_name: "Vivaldi"       );
198chromium!("macos", CocCoc  , base: "Library/Application Support/CocCoc/Browser"             , safe_name: "CocCoc"        );
199chromium!("macos", Arc     , base: "Library/Application Support/Arc/User Data"              , safe_name: "Arc"           );
200chromium!("macos", Opera   , base: "Library/Application Support/com.operasoftware.Opera"    , safe_name: "Opera"         );
201chromium!("macos", OperaGX , base: "Library/Application Support/com.operasoftware.OperaGX"  , cookies: "Cookies", login_data: "Login Data", safe_name: "Opera");
202chromium!("macos", Yandex  , base: "Library/Application Support/Yandex/YandexBrowser"       , login_data: "Default/Ya Passman Data", login_data_fa: "Default/Ya Passman Data", safe_name: "Yandex");
203
204chromium!("windows", Chrome  , base: r"AppData\Local\Google\Chrome\User Data"              );
205chromium!("windows", Edge    , base: r"AppData\Local\Microsoft\Edge\User Data"             );
206chromium!("windows", Chromium, base: r"AppData\Local\Chromium\User Data"                   );
207chromium!("windows", Brave   , base: r"AppData\Local\BraveSoftware\Brave-Browser\User Data");
208chromium!("windows", Vivaldi , base: r"AppData\Local\Vivaldi\User Data"                    );
209chromium!("windows", Opera   , base: r"AppData\Roaming\Opera Software\Opera Stable"        );
210chromium!("windows", OperaGX , base: r"AppData\Roaming\Opera Software\Opera GX Stable"     , cookies: r"Network\Cookies", login_data: r"Login Data", login_data_fa: r"Login Data For Account");
211chromium!("windows", CocCoc  , base: r"AppData\Local\CocCoc\Browser\User Data"             );
212chromium!("windows", Arc     , base: r"AppData\Local\Packages\TheBrowserCompany.Arc_ttt1ap7aakyb4\LocalCache\Local\Arc\User Data");
213chromium!("windows", Yandex  , base: r"AppData\Local\Yandex\YandexBrowser\User Data"       , login_data: r"Default\Ya Passman Data");