1use crate::{browser::mozilla::get_default_profile, config::Browser};
2use eyre::{anyhow, bail, Context, Result};
3use std::{env, path::PathBuf};
4
5fn expand_glob_paths(path: PathBuf) -> Result<Vec<PathBuf>> {
6 let mut paths: Vec<PathBuf> = vec![];
7 if let Some(path_str) = path.to_str() {
8 for entry in glob::glob(path_str)? {
9 if entry.is_ok() {
10 paths.push(entry?);
11 }
12 }
13 }
14 Ok(paths)
15}
16
17pub fn find_chrome_based_paths(config: &Browser) -> Result<(PathBuf, PathBuf)> {
18 for path in &config.paths {
19 let channels = config.channels.clone().unwrap_or(vec!["".to_string()]);
21 for channel in channels {
22 let path = path.replace("{channel}", &channel);
24 let db_path = expand_path(path.as_str())?;
25 let glob_db_paths = expand_glob_paths(db_path)?;
26 for db_path in glob_db_paths {
27 if db_path.exists() {
29 if let Some(parent) = db_path.parent() {
30 let key_path = ["../../Local State", "../Local State", "Local State"]
31 .iter()
32 .map(|p| parent.join(p))
33 .find(|p| p.exists())
34 .unwrap_or_else(|| parent.join("Local State"))
35 .canonicalize()
36 .context("canonicalize")?;
37 log::debug!(
38 "Found chrome path {}, {}",
39 db_path.display(),
40 key_path.display()
41 );
42 return Ok((key_path, db_path));
43 }
44 }
45 }
46 }
47 }
48 Err(anyhow!("can't find cookies file"))
49}
50
51pub fn find_mozilla_based_paths(config: &Browser) -> Result<PathBuf> {
52 for path in &config.paths {
53 let channels = config.channels.clone().unwrap_or(vec!["".to_string()]);
55 for channel in channels {
56 let path = path.replace("{channel}", &channel);
58 let firefox_path = expand_path(path.as_str())?;
59 let glob_paths = expand_glob_paths(firefox_path)?;
60 for path in glob_paths {
61 let profiles_path = path.join("profiles.ini");
63 let default_profile =
64 get_default_profile(profiles_path.as_path()).unwrap_or("".to_string());
65 let db_path = path.join(default_profile).join("cookies.sqlite");
66 if db_path.exists() {
67 log::debug!("Found mozilla path {}", db_path.display());
68 return Ok(db_path);
69 }
70 }
71 }
72 }
73
74 bail!("Can't find cookies file")
75}
76
77#[cfg(target_os = "macos")]
78pub fn find_safari_based_paths(config: &Browser) -> Result<PathBuf> {
79 for path in &config.paths {
80 let channels = config.channels.clone().unwrap_or(vec!["".to_string()]);
82 for channel in channels {
83 let path = path.replace("{channel}", &channel);
85 let safari_path = expand_path(path.as_str())?;
86 let glob_paths = expand_glob_paths(safari_path)?;
87 for path in glob_paths {
88 if path.exists() {
90 log::debug!("Found safari path {}", path.display());
91 return Ok(path);
92 }
93 }
94 }
95 }
96 bail!("Can't find cookies file")
97}
98
99#[cfg(target_os = "windows")]
100pub fn find_ie_based_paths(config: &Browser) -> Result<PathBuf> {
101 for path in &config.paths {
102 let channels = config.channels.clone().unwrap_or(vec!["".to_string()]);
104 for channel in channels {
105 let path = path.replace("{channel}", &channel);
108 let path = expand_path(path.as_str())?;
109 let glob_paths = expand_glob_paths(path)?;
110 for path in glob_paths {
111 if path.exists() {
113 log::debug!("Found IE path {}", path.display());
114 return Ok(path);
115 }
116 }
117 }
118 }
119
120 bail!("Can't find cookies file")
121}
122#[cfg(target_os = "windows")]
123pub fn expand_path(path: &str) -> Result<PathBuf> {
124 use regex::Regex;
125 let re = Regex::new(r"%([^%]+)%")?;
127
128 let mut expanded_path = path.to_owned();
130
131 for capture in re.captures_iter(path) {
133 let placeholder = &capture[1];
135
136 if let Ok(var_value) = env::var(placeholder) {
138 expanded_path = expanded_path.replace(&capture[0], &var_value);
140 }
141 }
142
143 let path_buf = PathBuf::from(expanded_path);
145
146 Ok(path_buf)
147}
148
149#[cfg(unix)]
150pub fn expand_path(path: &str) -> Result<PathBuf> {
151 let home = env::var("HOME")?;
153
154 let expanded_path = path.replace('~', &home).replace("$HOME", &home);
156
157 Ok(PathBuf::from(expanded_path))
159}