chore: formatting

This commit is contained in:
zhom committed 2025-08-19 13:47:19 +04:00
1 parent 8e299fddd4
commit d91c97dd85
2 files changed
+63 -47

No files matched your search

+26 -17
View File
@@ -281,8 +281,8 @@ impl ProfileManager {
} }
// Find the profile by ID // Find the profile by ID
let profile_uuid = uuid::Uuid::parse_str(profile_id) let profile_uuid =
.map_err(|_| format!("Invalid profile ID: {profile_id}"))?; uuid::Uuid::parse_str(profile_id).map_err(|_| format!("Invalid profile ID: {profile_id}"))?;
let mut profile = existing_profiles let mut profile = existing_profiles
.into_iter() .into_iter()
.find(|p| p.id == profile_uuid) .find(|p| p.id == profile_uuid)
@@ -315,8 +315,8 @@ impl ProfileManager {
println!("Attempting to delete profile with ID: {profile_id}"); println!("Attempting to delete profile with ID: {profile_id}");
// Find the profile by ID // Find the profile by ID
let profile_uuid = uuid::Uuid::parse_str(profile_id) let profile_uuid =
.map_err(|_| format!("Invalid profile ID: {profile_id}"))?; uuid::Uuid::parse_str(profile_id).map_err(|_| format!("Invalid profile ID: {profile_id}"))?;
let profiles = self.list_profiles()?; let profiles = self.list_profiles()?;
let profile = profiles let profile = profiles
.into_iter() .into_iter()
@@ -345,7 +345,10 @@ impl ProfileManager {
return Err(format!("Failed to completely delete profile '{}'", profile.name).into()); return Err(format!("Failed to completely delete profile '{}'", profile.name).into());
} }
println!("Profile '{}' (ID: {}) deleted successfully", profile.name, profile_id); println!(
"Profile '{}' (ID: {}) deleted successfully",
profile.name, profile_id
);
// Rebuild tag suggestions after deletion // Rebuild tag suggestions after deletion
let _ = crate::tag_manager::TAG_MANAGER.lock().map(|tm| { let _ = crate::tag_manager::TAG_MANAGER.lock().map(|tm| {
@@ -367,8 +370,8 @@ impl ProfileManager {
version: &str, version: &str,
) -> Result<BrowserProfile, Box<dyn std::error::Error>> { ) -> Result<BrowserProfile, Box<dyn std::error::Error>> {
// Find the profile by ID // Find the profile by ID
let profile_uuid = uuid::Uuid::parse_str(profile_id) let profile_uuid =
.map_err(|_| format!("Invalid profile ID: {profile_id}"))?; uuid::Uuid::parse_str(profile_id).map_err(|_| format!("Invalid profile ID: {profile_id}"))?;
let profiles = self.list_profiles()?; let profiles = self.list_profiles()?;
let mut profile = profiles let mut profile = profiles
.into_iter() .into_iter()
@@ -462,8 +465,8 @@ impl ProfileManager {
tags: Vec<String>, tags: Vec<String>,
) -> Result<BrowserProfile, Box<dyn std::error::Error>> { ) -> Result<BrowserProfile, Box<dyn std::error::Error>> {
// Find the profile by ID // Find the profile by ID
let profile_uuid = uuid::Uuid::parse_str(profile_id) let profile_uuid =
.map_err(|_| format!("Invalid profile ID: {profile_id}"))?; uuid::Uuid::parse_str(profile_id).map_err(|_| format!("Invalid profile ID: {profile_id}"))?;
let profiles = self.list_profiles()?; let profiles = self.list_profiles()?;
let mut profile = profiles let mut profile = profiles
.into_iter() .into_iter()
@@ -514,7 +517,8 @@ impl ProfileManager {
if profile.process_id.is_some() { if profile.process_id.is_some() {
return Err( return Err(
format!( format!(
"Cannot delete profile '{}' while browser is running. Please stop the browser first.", profile.name "Cannot delete profile '{}' while browser is running. Please stop the browser first.",
profile.name
) )
.into(), .into(),
); );
@@ -544,10 +548,11 @@ impl ProfileManager {
config: CamoufoxConfig, config: CamoufoxConfig,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Find the profile by ID // Find the profile by ID
let profile_uuid = uuid::Uuid::parse_str(profile_id) let profile_uuid = uuid::Uuid::parse_str(profile_id).map_err(
.map_err(|_| -> Box<dyn std::error::Error + Send + Sync> { |_| -> Box<dyn std::error::Error + Send + Sync> {
format!("Invalid profile ID: {profile_id}").into() format!("Invalid profile ID: {profile_id}").into()
})?; },
)?;
let profiles = let profiles =
self self
.list_profiles() .list_profiles()
@@ -582,7 +587,10 @@ impl ProfileManager {
format!("Failed to save profile: {e}").into() format!("Failed to save profile: {e}").into()
})?; })?;
println!("Camoufox configuration updated for profile '{}' (ID: {}).", profile.name, profile_id); println!(
"Camoufox configuration updated for profile '{}' (ID: {}).",
profile.name, profile_id
);
// Emit profile config update event // Emit profile config update event
if let Err(e) = app_handle.emit("profiles-changed", ()) { if let Err(e) = app_handle.emit("profiles-changed", ()) {
@@ -599,10 +607,11 @@ impl ProfileManager {
proxy_id: Option<String>, proxy_id: Option<String>,
) -> Result<BrowserProfile, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<BrowserProfile, Box<dyn std::error::Error + Send + Sync>> {
// Find the profile by ID // Find the profile by ID
let profile_uuid = uuid::Uuid::parse_str(profile_id) let profile_uuid = uuid::Uuid::parse_str(profile_id).map_err(
.map_err(|_| -> Box<dyn std::error::Error + Send + Sync> { |_| -> Box<dyn std::error::Error + Send + Sync> {
format!("Invalid profile ID: {profile_id}").into() format!("Invalid profile ID: {profile_id}").into()
})?; },
)?;
let profiles = let profiles =
self self
.list_profiles() .list_profiles()
+37 -30
View File
@@ -8,9 +8,9 @@ use crate::version_updater;
use aes_gcm::{ use aes_gcm::{
aead::{Aead, AeadCore, KeyInit, OsRng}, aead::{Aead, AeadCore, KeyInit, OsRng},
Aes256Gcm, Key, Nonce Aes256Gcm, Key, Nonce,
}; };
use argon2::{Argon2, PasswordHasher, password_hash::SaltString}; use argon2::{password_hash::SaltString, Argon2, PasswordHasher};
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TableSortingSettings { pub struct TableSortingSettings {
@@ -213,41 +213,43 @@ impl SettingsManager {
} }
let vault_password = Self::get_vault_password(); let vault_password = Self::get_vault_password();
// Generate a random salt for Argon2 // Generate a random salt for Argon2
let salt = SaltString::generate(&mut OsRng); let salt = SaltString::generate(&mut OsRng);
// Use Argon2 to derive a 32-byte key from the vault password // Use Argon2 to derive a 32-byte key from the vault password
let argon2 = Argon2::default(); let argon2 = Argon2::default();
let password_hash = argon2.hash_password(vault_password.as_bytes(), &salt) let password_hash = argon2
.map_err(|e| format!("Argon2 key derivation failed: {}", e))?; .hash_password(vault_password.as_bytes(), &salt)
.map_err(|e| format!("Argon2 key derivation failed: {e}"))?;
let hash_value = password_hash.hash.unwrap(); let hash_value = password_hash.hash.unwrap();
let hash_bytes = hash_value.as_bytes(); let hash_bytes = hash_value.as_bytes();
// Take first 32 bytes for AES-256 key // Take first 32 bytes for AES-256 key
let key = Key::<Aes256Gcm>::from_slice(&hash_bytes[..32]); let key = Key::<Aes256Gcm>::from_slice(&hash_bytes[..32]);
let cipher = Aes256Gcm::new(key); let cipher = Aes256Gcm::new(key);
// Generate a random nonce // Generate a random nonce
let nonce = Aes256Gcm::generate_nonce(&mut OsRng); let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
// Encrypt the token // Encrypt the token
let ciphertext = cipher.encrypt(&nonce, token.as_bytes()) let ciphertext = cipher
.map_err(|e| format!("Encryption failed: {}", e))?; .encrypt(&nonce, token.as_bytes())
.map_err(|e| format!("Encryption failed: {e}"))?;
// Create file data with header, salt, nonce, and encrypted data // Create file data with header, salt, nonce, and encrypted data
let mut file_data = Vec::new(); let mut file_data = Vec::new();
file_data.extend_from_slice(b"DBAPI"); // 5-byte header file_data.extend_from_slice(b"DBAPI"); // 5-byte header
file_data.push(2u8); // Version 2 (Argon2 + AES-GCM) file_data.push(2u8); // Version 2 (Argon2 + AES-GCM)
// Store salt length and salt // Store salt length and salt
let salt_str = salt.as_str(); let salt_str = salt.as_str();
file_data.push(salt_str.len() as u8); file_data.push(salt_str.len() as u8);
file_data.extend_from_slice(salt_str.as_bytes()); file_data.extend_from_slice(salt_str.as_bytes());
// Store nonce (12 bytes for AES-GCM) // Store nonce (12 bytes for AES-GCM)
file_data.extend_from_slice(&nonce); file_data.extend_from_slice(&nonce);
// Store ciphertext length and ciphertext // Store ciphertext length and ciphertext
file_data.extend_from_slice(&(ciphertext.len() as u32).to_le_bytes()); file_data.extend_from_slice(&(ciphertext.len() as u32).to_le_bytes());
file_data.extend_from_slice(&ciphertext); file_data.extend_from_slice(&ciphertext);
@@ -274,22 +276,22 @@ impl SettingsManager {
} }
let version = file_data[5]; let version = file_data[5];
// Only support Argon2 + AES-GCM (version 2) // Only support Argon2 + AES-GCM (version 2)
if version != 2 { if version != 2 {
return Ok(None); return Ok(None);
} }
// Argon2 + AES-GCM decryption // Argon2 + AES-GCM decryption
let mut offset = 6; let mut offset = 6;
// Read salt // Read salt
if offset >= file_data.len() { if offset >= file_data.len() {
return Ok(None); return Ok(None);
} }
let salt_len = file_data[offset] as usize; let salt_len = file_data[offset] as usize;
offset += 1; offset += 1;
if offset + salt_len > file_data.len() { if offset + salt_len > file_data.len() {
return Ok(None); return Ok(None);
} }
@@ -297,7 +299,7 @@ impl SettingsManager {
let salt_str = std::str::from_utf8(salt_bytes).map_err(|_| "Invalid salt encoding")?; let salt_str = std::str::from_utf8(salt_bytes).map_err(|_| "Invalid salt encoding")?;
let salt = SaltString::from_b64(salt_str).map_err(|_| "Invalid salt format")?; let salt = SaltString::from_b64(salt_str).map_err(|_| "Invalid salt format")?;
offset += salt_len; offset += salt_len;
// Read nonce (12 bytes) // Read nonce (12 bytes)
if offset + 12 > file_data.len() { if offset + 12 > file_data.len() {
return Ok(None); return Ok(None);
@@ -305,36 +307,41 @@ impl SettingsManager {
let nonce_bytes = &file_data[offset..offset + 12]; let nonce_bytes = &file_data[offset..offset + 12];
let nonce = Nonce::from_slice(nonce_bytes); let nonce = Nonce::from_slice(nonce_bytes);
offset += 12; offset += 12;
// Read ciphertext // Read ciphertext
if offset + 4 > file_data.len() { if offset + 4 > file_data.len() {
return Ok(None); return Ok(None);
} }
let ciphertext_len = u32::from_le_bytes([ let ciphertext_len = u32::from_le_bytes([
file_data[offset], file_data[offset + 1], file_data[offset + 2], file_data[offset + 3] file_data[offset],
file_data[offset + 1],
file_data[offset + 2],
file_data[offset + 3],
]) as usize; ]) as usize;
offset += 4; offset += 4;
if offset + ciphertext_len > file_data.len() { if offset + ciphertext_len > file_data.len() {
return Ok(None); return Ok(None);
} }
let ciphertext = &file_data[offset..offset + ciphertext_len]; let ciphertext = &file_data[offset..offset + ciphertext_len];
// Derive key using Argon2 // Derive key using Argon2
let vault_password = Self::get_vault_password(); let vault_password = Self::get_vault_password();
let argon2 = Argon2::default(); let argon2 = Argon2::default();
let password_hash = argon2.hash_password(vault_password.as_bytes(), &salt) let password_hash = argon2
.map_err(|e| format!("Argon2 key derivation failed: {}", e))?; .hash_password(vault_password.as_bytes(), &salt)
.map_err(|e| format!("Argon2 key derivation failed: {e}"))?;
let hash_value = password_hash.hash.unwrap(); let hash_value = password_hash.hash.unwrap();
let hash_bytes = hash_value.as_bytes(); let hash_bytes = hash_value.as_bytes();
let key = Key::<Aes256Gcm>::from_slice(&hash_bytes[..32]); let key = Key::<Aes256Gcm>::from_slice(&hash_bytes[..32]);
let cipher = Aes256Gcm::new(key); let cipher = Aes256Gcm::new(key);
// Decrypt the token // Decrypt the token
let plaintext = cipher.decrypt(nonce, ciphertext) let plaintext = cipher
.decrypt(nonce, ciphertext)
.map_err(|_| "Decryption failed")?; .map_err(|_| "Decryption failed")?;
match String::from_utf8(plaintext) { match String::from_utf8(plaintext) {
Ok(token) => Ok(Some(token)), Ok(token) => Ok(Some(token)),
Err(_) => Ok(None), Err(_) => Ok(None),