refactor: ui cleanup

This commit is contained in:
zhom
2026-05-15 15:44:20 +04:00
parent 56b0da990b
commit c8a43b43f1
35 changed files with 3792 additions and 1674 deletions
+24
View File
@@ -473,6 +473,8 @@ impl ProfileManager {
// Save profile with new name
self.save_profile(&profile)?;
crate::sync::queue_profile_sync_if_eligible(&profile);
// Keep tag suggestions up to date after name change (rebuild from all profiles)
let _ = crate::tag_manager::TAG_MANAGER.lock().map(|tm| {
let _ = tm.rebuild_from_profiles(&self.list_profiles().unwrap_or_default());
@@ -678,6 +680,8 @@ impl ProfileManager {
profile.group_id = group_id.clone();
self.save_profile(&profile)?;
crate::sync::queue_profile_sync_if_eligible(&profile);
// Auto-enable sync for new group if profile has sync enabled
if profile.is_sync_enabled() {
if let Some(ref new_group_id) = group_id {
@@ -732,6 +736,8 @@ impl ProfileManager {
// Save profile
self.save_profile(&profile)?;
crate::sync::queue_profile_sync_if_eligible(&profile);
// Update global tag suggestions from all profiles
let _ = crate::tag_manager::TAG_MANAGER.lock().map(|tm| {
let _ = tm.rebuild_from_profiles(&self.list_profiles().unwrap_or_default());
@@ -766,6 +772,8 @@ impl ProfileManager {
// Save profile
self.save_profile(&profile)?;
crate::sync::queue_profile_sync_if_eligible(&profile);
// Emit profile note update event
if let Err(e) = events::emit_empty("profiles-changed") {
log::warn!("Warning: Failed to emit profiles-changed event: {e}");
@@ -792,6 +800,8 @@ impl ProfileManager {
self.save_profile(&profile)?;
crate::sync::queue_profile_sync_if_eligible(&profile);
if let Err(e) = events::emit("profile-updated", &profile) {
log::warn!("Warning: Failed to emit profile update event: {e}");
}
@@ -821,6 +831,8 @@ impl ProfileManager {
self.save_profile(&profile)?;
crate::sync::queue_profile_sync_if_eligible(&profile);
if let Err(e) = events::emit_empty("profiles-changed") {
log::warn!("Warning: Failed to emit profiles-changed event: {e}");
}
@@ -845,6 +857,8 @@ impl ProfileManager {
self.save_profile(&profile)?;
crate::sync::queue_profile_sync_if_eligible(&profile);
if let Err(e) = events::emit_empty("profiles-changed") {
log::warn!("Warning: Failed to emit profiles-changed event: {e}");
}
@@ -1060,6 +1074,8 @@ impl ProfileManager {
format!("Failed to save profile: {e}").into()
})?;
crate::sync::queue_profile_sync_if_eligible(&profile);
log::info!(
"Camoufox configuration updated for profile '{}' (ID: {}).",
profile.name,
@@ -1120,6 +1136,8 @@ impl ProfileManager {
format!("Failed to save profile: {e}").into()
})?;
crate::sync::queue_profile_sync_if_eligible(&profile);
log::info!(
"Wayfern configuration updated for profile '{}' (ID: {}).",
profile.name,
@@ -1174,6 +1192,8 @@ impl ProfileManager {
format!("Failed to save profile: {e}").into()
})?;
crate::sync::queue_profile_sync_if_eligible(&profile);
// Auto-enable sync for new proxy if profile has sync enabled
if profile.is_sync_enabled() {
if let Some(ref new_proxy_id) = proxy_id {
@@ -1263,6 +1283,8 @@ impl ProfileManager {
format!("Failed to save profile: {e}").into()
})?;
crate::sync::queue_profile_sync_if_eligible(&profile);
// Auto-enable sync for the new VPN if profile has sync enabled.
if profile.is_sync_enabled() {
if let Some(ref new_vpn_id) = vpn_id {
@@ -1300,6 +1322,8 @@ impl ProfileManager {
profile.extension_group_id = extension_group_id.clone();
self.save_profile(&profile)?;
crate::sync::queue_profile_sync_if_eligible(&profile);
// Auto-enable sync for the new extension group if profile has sync
// enabled. The helper is sync internally; we fire-and-forget through
// the async runtime so any I/O doesn't block this caller.
+37
View File
@@ -292,10 +292,45 @@ pub async fn set_profile_password(profile_id: String, password: String) -> Resul
.map_err(err_internal)?;
cache_key(id, key);
crate::sync::queue_profile_sync_if_eligible(&profile);
emit_profiles_changed();
Ok(())
}
/// Verify a profile password without unlocking. Used by the Settings UI's
/// "Validate" button so users can confirm they remember the password without
/// performing a destructive change. Honors the same lockout schedule as
/// `unlock_profile` so a brute-force attacker can't bypass rate-limiting by
/// hammering this command.
#[tauri::command]
pub async fn verify_profile_password(profile_id: String, password: String) -> Result<(), String> {
let id = parse_uuid(&profile_id)?;
let profile = load_profile(&id)?;
if !profile.password_protected {
return Err(err_code("PROFILE_NOT_PROTECTED"));
}
if let Err(secs) = check_lockout(&id) {
return Err(err_with("LOCKED_OUT", &[("seconds", secs.to_string())]));
}
let salt = profile
.encryption_salt
.as_deref()
.ok_or_else(|| err_code("PROFILE_MISSING_SALT"))?;
let key = derive_profile_key(&password, salt).map_err(err_internal)?;
let dir = profile_data_dir(&profile);
match verify_key_against_dir(&key, &dir) {
Ok(()) => {
clear_failed_attempts(&id);
Ok(())
}
Err(crate::profile::encryption::PasswordError::WrongPassword) => {
record_failed_attempt(id);
Err(err_code("INCORRECT_PASSWORD"))
}
Err(other) => Err(err_internal(other)),
}
}
#[tauri::command]
pub async fn unlock_profile(profile_id: String, password: String) -> Result<(), String> {
let id = parse_uuid(&profile_id)?;
@@ -396,6 +431,7 @@ pub async fn change_profile_password(
drop_cached_key(&id);
cache_key(id, new_key);
crate::sync::queue_profile_sync_if_eligible(&profile);
emit_profiles_changed();
Ok(())
}
@@ -464,6 +500,7 @@ pub async fn remove_profile_password(profile_id: String, password: String) -> Re
.map_err(err_internal)?;
drop_cached_key(&id);
crate::sync::queue_profile_sync_if_eligible(&profile);
emit_profiles_changed();
Ok(())
}