From 3398b2cbcd03262b387f18a17c6eae495eb996c4 Mon Sep 17 00:00:00 2001 From: jake <77554505+brxken128@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:32:48 +0000 Subject: [PATCH] [ENG-1540] Remove `localStorage` if no libraries are created (#1945) * feat: clear localstorage on start if no libraries are found * chore: add a check to see if the node is for desktop or server use this will prevent desktop/app localstorage from being cleared if it's a server being hosted * fix: add secondary localstorage directory for macos for some reason the app/onboarding progress is kept in `Library/WebKit/Spacedrive` (at least in dev?) so it also needs clearing * feat: delete cache directories also * chore: iterate over paths * feat: add support for windows `localStorage` by using `data_local_dir` * docs/style: better comments and logs * feat: remove both `AppData` local and roaming on Windows * fix: mobile builds * chore: tweak error message for windows --- apps/desktop/src-tauri/src/main.rs | 2 +- apps/mobile/modules/sd-core/core/src/lib.rs | 2 +- apps/server/src/main.rs | 1 + core/src/lib.rs | 7 ++++ core/src/util/clear_localstorage.rs | 44 +++++++++++++++++++++ core/src/util/mod.rs | 1 + 6 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 core/src/util/clear_localstorage.rs diff --git a/apps/desktop/src-tauri/src/main.rs b/apps/desktop/src-tauri/src/main.rs index 2f87f8224..68c2186c3 100644 --- a/apps/desktop/src-tauri/src/main.rs +++ b/apps/desktop/src-tauri/src/main.rs @@ -182,7 +182,7 @@ async fn main() -> tauri::Result<()> { let (_guard, result) = match Node::init_logger(&data_dir) { Ok(guard) => ( Some(guard), - Node::new(data_dir, sd_core::Env::new(CLIENT_ID)).await, + Node::new(data_dir, sd_core::Env::new(CLIENT_ID), true).await, ), Err(err) => (None, Err(NodeError::Logger(err))), }; diff --git a/apps/mobile/modules/sd-core/core/src/lib.rs b/apps/mobile/modules/sd-core/core/src/lib.rs index 891bab37b..512ec8bad 100644 --- a/apps/mobile/modules/sd-core/core/src/lib.rs +++ b/apps/mobile/modules/sd-core/core/src/lib.rs @@ -75,7 +75,7 @@ pub fn handle_core_msg( let _guard = Node::init_logger(&data_dir); // TODO: probably don't unwrap - let new_node = Node::new(data_dir, sd_core::Env::new(CLIENT_ID)) + let new_node = Node::new(data_dir, sd_core::Env::new(CLIENT_ID), false) .await .unwrap(); node.replace(new_node.clone()); diff --git a/apps/server/src/main.rs b/apps/server/src/main.rs index 8d80008b2..61c3c98a0 100644 --- a/apps/server/src/main.rs +++ b/apps/server/src/main.rs @@ -47,6 +47,7 @@ async fn main() { client_id: std::env::var("SD_CLIENT_ID") .unwrap_or_else(|_| "04701823-a498-406e-aef9-22081c1dae34".to_string()), }, + false, ) .await { diff --git a/core/src/lib.rs b/core/src/lib.rs index 552a61ef8..bb109e4bc 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -4,6 +4,7 @@ use crate::{ api::{CoreEvent, Router}, location::LocationManagerError, object::media::thumbnail::actor::Thumbnailer, + util::clear_localstorage::clear_localstorage, }; #[cfg(feature = "ai")] @@ -82,6 +83,7 @@ impl Node { pub async fn new( data_dir: impl AsRef, env: env::Env, + desktop: bool, ) -> Result<(Arc, Arc), NodeError> { let data_dir = data_dir.as_ref(); @@ -108,6 +110,11 @@ impl Node { let (locations, locations_actor) = location::Locations::new(); let (jobs, jobs_actor) = job::Jobs::new(); let libraries = library::Libraries::new(data_dir.join("libraries")).await?; + + if desktop && libraries.get_all().await.is_empty() { + clear_localstorage().await; + } + let (p2p, p2p_actor) = p2p::P2PManager::new(config.clone(), libraries.clone()).await?; let node = Arc::new(Node { data_dir: data_dir.to_path_buf(), diff --git a/core/src/util/clear_localstorage.rs b/core/src/util/clear_localstorage.rs new file mode 100644 index 000000000..c70afe362 --- /dev/null +++ b/core/src/util/clear_localstorage.rs @@ -0,0 +1,44 @@ +use directories::BaseDirs; +use tokio::fs; +use tracing::{info, warn}; + +#[cfg(target_os = "linux")] +const EXTRA_DIRS: [&str; 1] = [".cache/spacedrive"]; +#[cfg(target_os = "macos")] +const EXTRA_DIRS: [&str; 2] = ["Library/WebKit/Spacedrive", "Library/Caches/Spacedrive"]; + +pub async fn clear_localstorage() { + if let Some(base_dir) = BaseDirs::new() { + let data_dir = base_dir.data_dir().join("com.spacedrive.desktop"); // maybe tie this into something static? + + fs::remove_dir_all(&data_dir) + .await + .map_err(|_| warn!("Unable to delete the `localStorage` primary directory.")) + .ok(); + + // Windows needs both AppData/Local and AppData/Roaming clearing as it stores data in both + #[cfg(target_os = "windows")] + fs::remove_dir_all(&base_dir.data_local_dir().join("com.spacedrive.desktop")) + .await + .map_err(|_| warn!("Unable to delete the `localStorage` directory in Local AppData.")) + .ok(); + + info!("Deleted {}", data_dir.display()); + + let home_dir = base_dir.home_dir(); + + #[cfg(any(target_os = "linux", target_os = "macos"))] + for path in EXTRA_DIRS { + fs::remove_dir_all(home_dir.join(path)) + .await + .map_err(|_| warn!("Unable to delete a `localStorage` cache: {path}")) + .ok(); + + info!("Deleted {path}"); + } + + info!("Successfully wiped `localStorage` and related caches.") + } else { + warn!("Unable to source `BaseDirs` in order to clear `localStorage`.") + } +} diff --git a/core/src/util/mod.rs b/core/src/util/mod.rs index e8096c65b..d549857a6 100644 --- a/core/src/util/mod.rs +++ b/core/src/util/mod.rs @@ -1,5 +1,6 @@ mod abort_on_drop; mod batched_stream; +pub mod clear_localstorage; #[cfg(debug_assertions)] pub mod debug_initializer; mod infallible_request;