diff --git a/frontend/appflowy_flutter/macos/Podfile.lock b/frontend/appflowy_flutter/macos/Podfile.lock index e06670c5a5..f4bedfef79 100644 --- a/frontend/appflowy_flutter/macos/Podfile.lock +++ b/frontend/appflowy_flutter/macos/Podfile.lock @@ -144,34 +144,34 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos SPEC CHECKSUMS: - app_links: 9028728e32c83a0831d9db8cf91c526d16cc5468 - appflowy_backend: 464aeb3e5c6966a41641a2111e5ead72ce2695f7 - auto_updater_macos: 3a42f1a06be6981f1a18be37e6e7bf86aa732118 - bitsdojo_window_macos: 7959fb0ca65a3ccda30095c181ecb856fae48ea9 - connectivity_plus: e74b9f74717d2d99d45751750e266e55912baeb5 - desktop_drop: e0b672a7d84c0a6cbc378595e82cdb15f2970a43 - device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76 - file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31 - flowy_infra_ui: 8760ff42a789de40bf5007a5f176b454722a341e + app_links: 10e0a0ab602ffaf34d142cd4862f29d34b303b2a + appflowy_backend: 865496343de667fc8c600e04b9fd05234e130cf9 + auto_updater_macos: 3e3462c418fe4e731917eacd8d28eef7af84086d + bitsdojo_window_macos: 44e3b8fe3dd463820e0321f6256c5b1c16bb6a00 + connectivity_plus: 18d3c32514c886e046de60e9c13895109866c747 + desktop_drop: 69eeff437544aa619c8db7f4481b3a65f7696898 + device_info_plus: 1b14eed9bf95428983aed283a8d51cce3d8c4215 + file_selector_macos: cc3858c981fe6889f364731200d6232dac1d812d + flowy_infra_ui: 03301a39ad118771adbf051a664265c61c507f38 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 HotKey: 400beb7caa29054ea8d864c96f5ba7e5b4852277 - hotkey_manager: b443f35f4d772162937aa73fd8995e579f8ac4e2 - irondash_engine_context: 893c7d96d20ce361d7e996f39d360c4c2f9869ba - local_notifier: ebf072651e35ae5e47280ad52e2707375cb2ae4e - package_info_plus: f0052d280d17aa382b932f399edf32507174e870 - path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 + hotkey_manager: c32bf0bfe8f934b7bc17ab4ad5c4c142960b023c + irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478 + local_notifier: e9506bc66fc70311e8bc7291fb70f743c081e4ff + package_info_plus: 12f1c5c2cfe8727ca46cbd0b26677728972d9a5b + path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda - screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f + screen_retriever_macos: 776e0fa5d42c6163d2bf772d22478df4b302b161 Sentry: 1fe34e9c2cbba1e347623610d26db121dcb569f1 - sentry_flutter: e24b397f9a61fa5bbefd8279c3b2242ca86faa90 - share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc - shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 + sentry_flutter: a39c2a2d67d5e5b9cb0b94a4985c76dd5b3fc737 + share_plus: 1fa619de8392a4398bfaf176d441853922614e89 + shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 Sparkle: 5f8960a7a119aa7d45dacc0d5837017170bc5675 - sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 - super_native_extensions: c2795d6d9aedf4a79fae25cb6160b71b50549189 - url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673 - webview_flutter_wkwebview: 44d4dee7d7056d5ad185d25b38404436d56c547c - window_manager: 1d01fa7ac65a6e6f83b965471b1a7fdd3f06166c + sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d + super_native_extensions: 85efee3a7495b46b04befcfc86ed12069264ebf3 + url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404 + webview_flutter_wkwebview: 0982481e3d9c78fd5c6f62a002fcd24fc791f1e4 + window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8 PODFILE CHECKSUM: 0532f3f001ca3110b8be345d6491fff690e95823 diff --git a/frontend/rust-lib/event-integration-test/tests/user/migration_test/document_test.rs b/frontend/rust-lib/event-integration-test/tests/user/migration_test/document_test.rs index f3b73d55d3..f4ba5ec831 100644 --- a/frontend/rust-lib/event-integration-test/tests/user/migration_test/document_test.rs +++ b/frontend/rust-lib/event-integration-test/tests/user/migration_test/document_test.rs @@ -11,7 +11,6 @@ async fn migrate_historical_empty_document_test() { "historical_empty_document", ) .unwrap(); - let s = user_db_path.to_str().unwrap().to_string(); let test = EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await; diff --git a/frontend/rust-lib/flowy-ai/src/ai_manager.rs b/frontend/rust-lib/flowy-ai/src/ai_manager.rs index 2e9fc7e720..fd931bd73f 100644 --- a/frontend/rust-lib/flowy-ai/src/ai_manager.rs +++ b/frontend/rust-lib/flowy-ai/src/ai_manager.rs @@ -104,7 +104,7 @@ impl AIManager { } } - async fn reload_with_workspace_id(&self, workspace_id: &str) { + async fn reload_with_workspace_id(&self, workspace_id: &Uuid) { // Check if local AI is enabled for this workspace and if we're in local mode let result = self.user_service.is_local_model().await; if let Err(err) = &result { @@ -115,7 +115,9 @@ impl AIManager { } let is_local = result.unwrap_or(false); - let is_enabled = self.local_ai.is_enabled_on_workspace(workspace_id); + let is_enabled = self + .local_ai + .is_enabled_on_workspace(&workspace_id.to_string()); let is_running = self.local_ai.is_running(); info!( "[AI Manager] Reloading workspace: {}, is_local: {}, is_enabled: {}, is_running: {}", @@ -161,17 +163,17 @@ impl AIManager { } #[instrument(skip_all, err)] - pub async fn on_launch_if_authenticated(&self, workspace_id: &str) -> Result<(), FlowyError> { + pub async fn on_launch_if_authenticated(&self, workspace_id: &Uuid) -> Result<(), FlowyError> { self.reload_with_workspace_id(workspace_id).await; Ok(()) } - pub async fn initialize_after_sign_in(&self, workspace_id: &str) -> Result<(), FlowyError> { + pub async fn initialize_after_sign_in(&self, workspace_id: &Uuid) -> Result<(), FlowyError> { self.reload_with_workspace_id(workspace_id).await; Ok(()) } - pub async fn initialize_after_sign_up(&self, workspace_id: &str) -> Result<(), FlowyError> { + pub async fn initialize_after_sign_up(&self, workspace_id: &Uuid) -> Result<(), FlowyError> { self.reload_with_workspace_id(workspace_id).await; Ok(()) } @@ -181,9 +183,7 @@ impl AIManager { &self, workspace_id: &Uuid, ) -> Result<(), FlowyError> { - self - .reload_with_workspace_id(&workspace_id.to_string()) - .await; + self.reload_with_workspace_id(workspace_id).await; Ok(()) } diff --git a/frontend/rust-lib/flowy-core/src/user_state_callback.rs b/frontend/rust-lib/flowy-core/src/user_state_callback.rs index f191d3c1ad..1a1762f651 100644 --- a/frontend/rust-lib/flowy-core/src/user_state_callback.rs +++ b/frontend/rust-lib/flowy-core/src/user_state_callback.rs @@ -81,11 +81,10 @@ impl UserStatusCallback for UserStatusCallbackImpl { &self, user_id: i64, cloud_config: &Option, - user_workspace: &UserWorkspace, + workspace_id: &Uuid, _device_id: &str, auth_type: &AuthType, ) -> FlowyResult<()> { - let workspace_id = user_workspace.workspace_id()?; if let Some(cloud_config) = cloud_config { self .server_provider @@ -101,7 +100,7 @@ impl UserStatusCallback for UserStatusCallbackImpl { .folder_manager .initialize( user_id, - &workspace_id, + workspace_id, FolderInitDataSource::LocalDisk { create_if_not_exist: false, }, @@ -113,8 +112,8 @@ impl UserStatusCallback for UserStatusCallbackImpl { .await?; self.document_manager.initialize(user_id).await?; - let workspace_id = user_workspace.id.clone(); let cloned_ai_manager = self.ai_manager.clone(); + let workspace_id = *workspace_id; self.runtime.spawn(async move { if let Err(err) = cloned_ai_manager .on_launch_if_authenticated(&workspace_id) @@ -129,19 +128,18 @@ impl UserStatusCallback for UserStatusCallbackImpl { async fn on_sign_in( &self, user_id: i64, - user_workspace: &UserWorkspace, + workspace_id: &Uuid, device_id: &str, auth_type: &AuthType, ) -> FlowyResult<()> { event!( tracing::Level::TRACE, "Notify did sign in: latest_workspace: {:?}, device_id: {}", - user_workspace, + workspace_id, device_id ); - let workspace_id = user_workspace.workspace_id()?; let data_source = self - .folder_init_data_source(user_id, &workspace_id, auth_type) + .folder_init_data_source(user_id, workspace_id, auth_type) .await?; self .folder_manager @@ -158,7 +156,7 @@ impl UserStatusCallback for UserStatusCallbackImpl { self .ai_manager - .initialize_after_sign_in(&user_workspace.id) + .initialize_after_sign_in(workspace_id) .await?; Ok(()) @@ -168,7 +166,7 @@ impl UserStatusCallback for UserStatusCallbackImpl { &self, is_new_user: bool, user_profile: &UserProfile, - user_workspace: &UserWorkspace, + workspace_id: &Uuid, device_id: &str, auth_type: &AuthType, ) -> FlowyResult<()> { @@ -176,12 +174,11 @@ impl UserStatusCallback for UserStatusCallbackImpl { tracing::Level::TRACE, "Notify did sign up: is new: {} user_workspace: {:?}, device_id: {}", is_new_user, - user_workspace, + workspace_id, device_id ); - let workspace_id = user_workspace.workspace_id()?; let data_source = self - .folder_init_data_source(user_profile.uid, &workspace_id, auth_type) + .folder_init_data_source(user_profile.uid, workspace_id, auth_type) .await?; self @@ -191,7 +188,7 @@ impl UserStatusCallback for UserStatusCallbackImpl { &user_profile.token, is_new_user, data_source, - &workspace_id, + workspace_id, ) .await .context("FolderManager error")?; @@ -210,7 +207,7 @@ impl UserStatusCallback for UserStatusCallbackImpl { self .ai_manager - .initialize_after_sign_up(&user_workspace.id) + .initialize_after_sign_up(workspace_id) .await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-user-pub/src/session.rs b/frontend/rust-lib/flowy-user-pub/src/session.rs index 83a5670ddb..29b04efce5 100644 --- a/frontend/rust-lib/flowy-user-pub/src/session.rs +++ b/frontend/rust-lib/flowy-user-pub/src/session.rs @@ -1,106 +1,26 @@ -use crate::entities::{AuthType, UserAuthResponse, UserWorkspace}; -use base64::engine::general_purpose::STANDARD; -use base64::Engine; -use chrono::Utc; -use serde::de::{MapAccess, Visitor}; -use serde::{Deserialize, Deserializer, Serialize}; -use serde_json::Value; +use crate::entities::UserAuthResponse; +use serde::{Deserialize, Serialize}; use std::fmt; use std::fmt::Display; use uuid::Uuid; -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Session { pub user_id: i64, pub user_uuid: Uuid, - pub user_workspace: UserWorkspace, + pub workspace_id: String, } impl Display for Session { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "user_id: {}, user_workspace: {}:{}", - self.user_id, self.user_workspace.name, self.user_workspace.id, + "user_id: {}, user_workspace: {}", + self.user_id, self.workspace_id, ) } } -struct SessionVisitor; -impl<'de> Visitor<'de> for SessionVisitor { - type Value = Session; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("Session") - } - - fn visit_map(self, mut map: M) -> Result - where - M: MapAccess<'de>, - { - let mut user_id = None; - let mut user_uuid = None; - // For historical reasons, the session used to contain a workspace_id field. - // This field is no longer used, and is replaced by user_workspace. - let mut workspace_id = None; - let mut user_workspace = None; - - while let Some(key) = map.next_key::()? { - match key.as_str() { - "user_id" => { - user_id = Some(map.next_value()?); - }, - "user_uuid" => { - user_uuid = Some(map.next_value()?); - }, - "workspace_id" => { - workspace_id = Some(map.next_value()?); - }, - "user_workspace" => { - user_workspace = Some(map.next_value()?); - }, - _ => { - let _ = map.next_value::(); - }, - } - } - let user_id = user_id.ok_or(serde::de::Error::missing_field("user_id"))?; - let user_uuid = user_uuid.ok_or(serde::de::Error::missing_field("user_uuid"))?; - if user_workspace.is_none() { - if let Some(workspace_id) = workspace_id { - user_workspace = Some(UserWorkspace { - id: workspace_id, - name: "My Workspace".to_string(), - created_at: Utc::now(), - // For historical reasons, the database_storage_id is constructed by the user_id. - workspace_database_id: STANDARD.encode(format!("{}:user:database", user_id)), - icon: "".to_owned(), - member_count: 1, - role: None, - workspace_type: AuthType::Local, - }) - } - } - - let session = Session { - user_id, - user_uuid, - user_workspace: user_workspace.ok_or(serde::de::Error::missing_field("user_workspace"))?, - }; - - Ok(session) - } -} - -impl<'de> Deserialize<'de> for Session { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_any(SessionVisitor) - } -} - impl From<&T> for Session where T: UserAuthResponse, @@ -109,7 +29,7 @@ where Self { user_id: value.user_id(), user_uuid: *value.user_uuid(), - user_workspace: value.latest_workspace().clone(), + workspace_id: value.latest_workspace().clone().id, } } } diff --git a/frontend/rust-lib/flowy-user-pub/src/sql/workspace_sql.rs b/frontend/rust-lib/flowy-user-pub/src/sql/workspace_sql.rs index 27f63e3de6..dfd492e0af 100644 --- a/frontend/rust-lib/flowy-user-pub/src/sql/workspace_sql.rs +++ b/frontend/rust-lib/flowy-user-pub/src/sql/workspace_sql.rs @@ -99,6 +99,17 @@ pub fn select_user_workspace( Ok(row) } +pub fn select_user_workspace_type( + workspace_id: &str, + conn: &mut SqliteConnection, +) -> FlowyResult { + let row = dsl::user_workspace_table + .filter(user_workspace_table::id.eq(workspace_id)) + .select(user_workspace_table::workspace_type) + .first::(conn)?; + Ok(AuthType::from(row)) +} + pub fn select_all_user_workspace( uid: i64, conn: &mut SqliteConnection, diff --git a/frontend/rust-lib/flowy-user/src/event_handler.rs b/frontend/rust-lib/flowy-user/src/event_handler.rs index cbcf6f4477..ee6efb1006 100644 --- a/frontend/rust-lib/flowy-user/src/event_handler.rs +++ b/frontend/rust-lib/flowy-user/src/event_handler.rs @@ -94,12 +94,12 @@ pub async fn get_user_profile_handler( let session = manager.get_session()?; let mut user_profile = manager - .get_user_profile_from_disk(session.user_id, &session.user_workspace.id) + .get_user_profile_from_disk(session.user_id, &session.workspace_id) .await?; let weak_manager = Arc::downgrade(&manager); let cloned_user_profile = user_profile.clone(); - let workspace_id = session.user_workspace.id.clone(); + let workspace_id = session.workspace_id.clone(); // Refresh the user profile in the background tokio::spawn(async move { @@ -433,7 +433,7 @@ pub async fn get_all_workspace_handler( let manager = upgrade_manager(manager)?; let session = manager.get_session()?; let profile = manager - .get_user_profile_from_disk(session.user_id, &session.user_workspace.id) + .get_user_profile_from_disk(session.user_id, &session.workspace_id) .await?; let user_workspaces = manager .get_all_user_workspaces(profile.uid, profile.auth_type) @@ -822,7 +822,7 @@ pub async fn get_workspace_member_info( manager: AFPluginState>, ) -> DataResult { let manager = upgrade_manager(manager)?; - let workspace_id = manager.get_session()?.user_workspace.workspace_id()?; + let workspace_id = Uuid::parse_str(&manager.get_session()?.workspace_id)?; let member = manager .get_workspace_member_info(param.uid, &workspace_id) .await?; diff --git a/frontend/rust-lib/flowy-user/src/event_map.rs b/frontend/rust-lib/flowy-user/src/event_map.rs index ba242e6d46..17f0df0590 100644 --- a/frontend/rust-lib/flowy-user/src/event_map.rs +++ b/frontend/rust-lib/flowy-user/src/event_map.rs @@ -285,7 +285,7 @@ pub trait UserStatusCallback: Send + Sync + 'static { &self, _user_id: i64, _cloud_config: &Option, - _user_workspace: &UserWorkspace, + _workspace_id: &Uuid, _device_id: &str, _auth_type: &AuthType, ) -> FlowyResult<()> { @@ -300,7 +300,7 @@ pub trait UserStatusCallback: Send + Sync + 'static { async fn on_sign_in( &self, _user_id: i64, - _user_workspace: &UserWorkspace, + _workspace_id: &Uuid, _device_id: &str, _auth_type: &AuthType, ) -> FlowyResult<()> { @@ -312,7 +312,7 @@ pub trait UserStatusCallback: Send + Sync + 'static { &self, _is_new_user: bool, _user_profile: &UserProfile, - _user_workspace: &UserWorkspace, + _workspace_id: &Uuid, _device_id: &str, _auth_type: &AuthType, ) -> FlowyResult<()> { diff --git a/frontend/rust-lib/flowy-user/src/migrations/anon_user_workspace.rs b/frontend/rust-lib/flowy-user/src/migrations/anon_user_workspace.rs index 1b1c3f890f..01729906a1 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/anon_user_workspace.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/anon_user_workspace.rs @@ -5,11 +5,13 @@ use tracing::instrument; use collab_integrate::CollabKVDB; use flowy_error::FlowyResult; +use flowy_sqlite::kv::KVStorePreferences; use flowy_user_pub::entities::AuthType; use crate::migrations::migration::UserDataMigration; +use crate::migrations::session_migration::get_session_workspace; use flowy_user_pub::session::Session; -use flowy_user_pub::sql::upsert_user_workspace; +use flowy_user_pub::sql::{select_user_workspace, upsert_user_workspace}; pub struct AnonUserWorkspaceTableMigration; @@ -32,17 +34,21 @@ impl UserDataMigration for AnonUserWorkspaceTableMigration { #[instrument(name = "AnonUserWorkspaceTableMigration", skip_all, err)] fn run( &self, - session: &Session, + user: &Session, _collab_db: &Arc, user_auth_type: &AuthType, db: &mut SqliteConnection, + store_preferences: &Arc, ) -> FlowyResult<()> { // For historical reason, anon user doesn't have a workspace in user_workspace_table. // So we need to create a new entry for the anon user in the user_workspace_table. if matches!(user_auth_type, AuthType::Local) { - let mut user_workspace = session.user_workspace.clone(); - user_workspace.workspace_type = AuthType::Local; - upsert_user_workspace(session.user_id, *user_auth_type, user_workspace, db)?; + if let Some(mut user_workspace) = get_session_workspace(store_preferences) { + if select_user_workspace(&user_workspace.id, db).ok().is_none() { + user_workspace.workspace_type = AuthType::Local; + upsert_user_workspace(user.user_id, *user_auth_type, user_workspace, db)?; + } + } } Ok(()) diff --git a/frontend/rust-lib/flowy-user/src/migrations/doc_key_with_workspace.rs b/frontend/rust-lib/flowy-user/src/migrations/doc_key_with_workspace.rs index 735d8f1f49..4d8f304454 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/doc_key_with_workspace.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/doc_key_with_workspace.rs @@ -8,6 +8,7 @@ use tracing::{instrument, trace}; use collab_integrate::CollabKVDB; use flowy_error::FlowyResult; +use flowy_sqlite::kv::KVStorePreferences; use flowy_user_pub::entities::AuthType; use crate::migrations::migration::UserDataMigration; @@ -38,17 +39,15 @@ impl UserDataMigration for CollabDocKeyWithWorkspaceIdMigration { #[instrument(name = "CollabDocKeyWithWorkspaceIdMigration", skip_all, err)] fn run( &self, - session: &Session, + user: &Session, collab_db: &Arc, _user_auth_type: &AuthType, _db: &mut SqliteConnection, + _store_preferences: &Arc, ) -> FlowyResult<()> { - trace!( - "migrate key with workspace id:{}", - session.user_workspace.id - ); + trace!("migrate key with workspace id:{}", user.workspace_id); collab_db.with_write_txn(|txn| { - migrate_old_keys(txn, &session.user_workspace.id)?; + migrate_old_keys(txn, &user.workspace_id)?; Ok(()) })?; Ok(()) diff --git a/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs b/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs index 996386cb5e..26ead8b2a9 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/document_empty_content.rs @@ -12,6 +12,7 @@ use tracing::{event, instrument}; use collab_integrate::{CollabKVAction, CollabKVDB, PersistenceError}; use flowy_error::{FlowyError, FlowyResult}; +use flowy_sqlite::kv::KVStorePreferences; use flowy_user_pub::entities::AuthType; use crate::migrations::migration::UserDataMigration; @@ -40,10 +41,11 @@ impl UserDataMigration for HistoricalEmptyDocumentMigration { #[instrument(name = "HistoricalEmptyDocumentMigration", skip_all, err)] fn run( &self, - session: &Session, + user: &Session, collab_db: &Arc, user_auth_type: &AuthType, _db: &mut SqliteConnection, + _store_preferences: &Arc, ) -> FlowyResult<()> { // - The `empty document` struct has already undergone refactoring prior to the launch of the AppFlowy cloud version. // - Consequently, if a user is utilizing the AppFlowy cloud version, there is no need to perform any migration for the `empty document` struct. @@ -52,32 +54,26 @@ impl UserDataMigration for HistoricalEmptyDocumentMigration { return Ok(()); } collab_db.with_write_txn(|write_txn| { - let origin = CollabOrigin::Client(CollabClient::new(session.user_id, "phantom")); + let origin = CollabOrigin::Client(CollabClient::new(user.user_id, "phantom")); let folder_collab = match load_collab( - session.user_id, + user.user_id, write_txn, - &session.user_workspace.id, - &session.user_workspace.id, + &user.workspace_id, + &user.workspace_id, ) { Ok(fc) => fc, Err(_) => return Ok(()), }; - let folder = Folder::open(session.user_id, folder_collab, None) + let folder = Folder::open(user.user_id, folder_collab, None) .map_err(|err| PersistenceError::Internal(err.into()))?; if let Some(workspace_id) = folder.get_workspace_id() { let migration_views = folder.get_views_belong_to(&workspace_id); // For historical reasons, the first level documents are empty. So migrate them by inserting // the default document data. for view in migration_views { - if migrate_empty_document( - write_txn, - &origin, - &view, - session.user_id, - &session.user_workspace.id, - ) - .is_err() + if migrate_empty_document(write_txn, &origin, &view, user.user_id, &user.workspace_id) + .is_err() { event!( tracing::Level::ERROR, diff --git a/frontend/rust-lib/flowy-user/src/migrations/migration.rs b/frontend/rust-lib/flowy-user/src/migrations/migration.rs index 1cf8d6a943..563f36b952 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/migration.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/migration.rs @@ -75,7 +75,13 @@ impl UserLocalDataMigration { let migration_name = migration.name().to_string(); if !duplicated_names.contains(&migration_name) { - migration.run(&self.session, &self.collab_db, user_auth_type, &mut conn)?; + migration.run( + &self.session, + &self.collab_db, + user_auth_type, + &mut conn, + &self.kv, + )?; applied_migrations.push(migration.name().to_string()); save_migration_record(&mut conn, &migration_name); duplicated_names.push(migration_name); @@ -100,6 +106,7 @@ pub trait UserDataMigration { collab_db: &Arc, user_auth_type: &AuthType, db: &mut SqliteConnection, + store_preferences: &Arc, ) -> FlowyResult<()>; } diff --git a/frontend/rust-lib/flowy-user/src/migrations/session_migration.rs b/frontend/rust-lib/flowy-user/src/migrations/session_migration.rs index 847ab8a516..825d926933 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/session_migration.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/session_migration.rs @@ -1,45 +1,120 @@ -use crate::user_manager::manager_history_user::ANON_USER; +use chrono::Utc; use flowy_sqlite::kv::KVStorePreferences; -use flowy_user_pub::entities::AuthType; +use flowy_user_pub::entities::{AuthType, Role, UserWorkspace}; use flowy_user_pub::session::Session; -use serde_json::{json, Value}; +use serde::de::{MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_json::Value; +use std::fmt; use std::sync::Arc; use uuid::Uuid; -const MIGRATION_USER_NO_USER_UUID: &str = "migration_user_no_user_uuid"; +const MIGRATION_SESSION: &str = "migration_session_key"; +pub const SESSION_CACHE_KEY_BACKUP: &str = "session_cache_key_backup"; pub fn migrate_session( session_cache_key: &str, store_preferences: &Arc, ) -> Option { - if !store_preferences.get_bool_or_default(MIGRATION_USER_NO_USER_UUID) - && store_preferences - .set_bool(MIGRATION_USER_NO_USER_UUID, true) - .is_ok() + if !store_preferences.get_bool_or_default(MIGRATION_SESSION) + && store_preferences.set_bool(MIGRATION_SESSION, true).is_ok() { - if let Some(mut value) = store_preferences.get_object::(session_cache_key) { - if value.get("user_uuid").is_none() { - if let Some(map) = value.as_object_mut() { - map.insert("user_uuid".to_string(), json!(Uuid::new_v4())); - } - } - - if let Ok(new_session) = serde_json::from_value::(value) { - let _ = store_preferences.set_object(session_cache_key, &new_session); - } - } - } - - if let Some(mut session) = store_preferences.get_object::(session_cache_key) { - if let Some(anon_session) = store_preferences.get_object::(ANON_USER) { - if session.user_id == anon_session.user_id - && session.user_workspace.workspace_type != AuthType::Local - { - session.user_workspace.workspace_type = AuthType::Local; - let _ = store_preferences.set_object(session_cache_key, &session); - } + if let Some(session) = store_preferences.get_object::(session_cache_key) { + let _ = store_preferences.set_object(SESSION_CACHE_KEY_BACKUP, &session); + let new_session = Session { + user_id: session.user_id, + user_uuid: session.user_uuid, + workspace_id: session.user_workspace.id, + }; + let _ = store_preferences.set_object(session_cache_key, &new_session); } } store_preferences.get_object::(session_cache_key) } + +#[derive(Debug, Clone, Serialize)] +struct SessionBackup { + user_id: i64, + user_uuid: Uuid, + user_workspace: UserWorkspace, +} +pub fn get_session_workspace(store_preferences: &Arc) -> Option { + store_preferences + .get_object::(SESSION_CACHE_KEY_BACKUP) + .map(|v| v.user_workspace) +} + +struct SessionVisitor; +impl<'de> Visitor<'de> for SessionVisitor { + type Value = SessionBackup; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("SessionBackup") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'de>, + { + let mut user_id = None; + let mut user_uuid = None; + // For historical reasons, the session used to contain a workspace_id field. + // This field is no longer used, and is replaced by user_workspace. + let mut workspace_id = None; + let mut user_workspace = None; + + while let Some(key) = map.next_key::()? { + match key.as_str() { + "user_id" => { + user_id = Some(map.next_value()?); + }, + "user_uuid" => { + user_uuid = Some(map.next_value()?); + }, + "workspace_id" => { + workspace_id = Some(map.next_value()?); + }, + "user_workspace" => { + user_workspace = Some(map.next_value()?); + }, + _ => { + let _ = map.next_value::(); + }, + } + } + let user_id = user_id.ok_or(serde::de::Error::missing_field("user_id"))?; + let user_uuid = user_uuid.unwrap_or_else(Uuid::new_v4); + if user_workspace.is_none() { + if let Some(workspace_id) = workspace_id { + user_workspace = Some(UserWorkspace { + id: workspace_id, + name: "My Workspace".to_string(), + created_at: Utc::now(), + workspace_database_id: Uuid::new_v4().to_string(), + icon: "".to_owned(), + member_count: 1, + role: Some(Role::Owner), + workspace_type: AuthType::Local, + }) + } + } + + let session = SessionBackup { + user_id, + user_uuid, + user_workspace: user_workspace.ok_or(serde::de::Error::missing_field("user_workspace"))?, + }; + + Ok(session) + } +} + +impl<'de> Deserialize<'de> for SessionBackup { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_any(SessionVisitor) + } +} diff --git a/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs b/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs index d3cea0e976..eee4a114b8 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/workspace_and_favorite_v1.rs @@ -8,6 +8,7 @@ use tracing::instrument; use collab_integrate::{CollabKVAction, CollabKVDB}; use flowy_error::FlowyResult; +use flowy_sqlite::kv::KVStorePreferences; use flowy_user_pub::entities::AuthType; use crate::migrations::migration::UserDataMigration; @@ -38,19 +39,20 @@ impl UserDataMigration for FavoriteV1AndWorkspaceArrayMigration { #[instrument(name = "FavoriteV1AndWorkspaceArrayMigration", skip_all, err)] fn run( &self, - session: &Session, + user: &Session, collab_db: &Arc, _user_auth_type: &AuthType, _db: &mut SqliteConnection, + _store_preferences: &Arc, ) -> FlowyResult<()> { collab_db.with_write_txn(|write_txn| { if let Ok(collab) = load_collab( - session.user_id, + user.user_id, write_txn, - &session.user_workspace.id, - &session.user_workspace.id, + &user.workspace_id, + &user.workspace_id, ) { - let mut folder = Folder::open(session.user_id, collab, None) + let mut folder = Folder::open(user.user_id, collab, None) .map_err(|err| PersistenceError::Internal(err.into()))?; folder .body @@ -70,9 +72,9 @@ impl UserDataMigration for FavoriteV1AndWorkspaceArrayMigration { .encode_collab() .map_err(|err| PersistenceError::Internal(err.into()))?; write_txn.flush_doc( - session.user_id, - &session.user_workspace.id, - &session.user_workspace.id, + user.user_id, + &user.workspace_id, + &user.workspace_id, encode.state_vector.to_vec(), encode.doc_state.to_vec(), )?; diff --git a/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs b/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs index ee9156199e..38665f3c41 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/workspace_trash_v1.rs @@ -8,6 +8,7 @@ use tracing::instrument; use collab_integrate::{CollabKVAction, CollabKVDB}; use flowy_error::FlowyResult; +use flowy_sqlite::kv::KVStorePreferences; use flowy_user_pub::entities::AuthType; use crate::migrations::migration::UserDataMigration; @@ -36,19 +37,20 @@ impl UserDataMigration for WorkspaceTrashMapToSectionMigration { #[instrument(name = "WorkspaceTrashMapToSectionMigration", skip_all, err)] fn run( &self, - session: &Session, + user: &Session, collab_db: &Arc, _user_auth_type: &AuthType, _db: &mut SqliteConnection, + _store_preferences: &Arc, ) -> FlowyResult<()> { collab_db.with_write_txn(|write_txn| { if let Ok(collab) = load_collab( - session.user_id, + user.user_id, write_txn, - &session.user_workspace.id, - &session.user_workspace.id, + &user.workspace_id, + &user.workspace_id, ) { - let mut folder = Folder::open(session.user_id, collab, None) + let mut folder = Folder::open(user.user_id, collab, None) .map_err(|err| PersistenceError::Internal(err.into()))?; let trash_ids = folder .get_trash_v1() @@ -64,9 +66,9 @@ impl UserDataMigration for WorkspaceTrashMapToSectionMigration { .encode_collab() .map_err(|err| PersistenceError::Internal(err.into()))?; write_txn.flush_doc( - session.user_id, - &session.user_workspace.id, - &session.user_workspace.id, + user.user_id, + &user.workspace_id, + &user.workspace_id, encode.state_vector.to_vec(), encode.doc_state.to_vec(), )?; diff --git a/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs b/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs index b725a082f5..881f4dfdf7 100644 --- a/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs +++ b/frontend/rust-lib/flowy-user/src/services/authenticate_user.rs @@ -11,6 +11,7 @@ use flowy_sqlite::kv::KVStorePreferences; use flowy_sqlite::DBConnection; use flowy_user_pub::entities::{AuthType, UserWorkspace}; use flowy_user_pub::session::Session; +use flowy_user_pub::sql::{select_user_workspace, select_user_workspace_type}; use std::path::PathBuf; use std::str::FromStr; use std::sync::{Arc, Weak}; @@ -46,10 +47,9 @@ impl AuthenticateUser { pub async fn is_local_mode(&self) -> FlowyResult { let session = self.get_session()?; - Ok(matches!( - session.user_workspace.workspace_type, - AuthType::Local - )) + let mut conn = self.get_sqlite_connection(session.user_id)?; + let workspace_type = select_user_workspace_type(&session.workspace_id, &mut conn)?; + Ok(matches!(workspace_type, AuthType::Local)) } pub fn device_id(&self) -> FlowyResult { @@ -58,13 +58,15 @@ impl AuthenticateUser { pub fn workspace_id(&self) -> FlowyResult { let session = self.get_session()?; - let workspace_uuid = Uuid::from_str(&session.user_workspace.id)?; + let workspace_uuid = Uuid::from_str(&session.workspace_id)?; Ok(workspace_uuid) } pub fn workspace_database_object_id(&self) -> FlowyResult { let session = self.get_session()?; - let id = Uuid::from_str(&session.user_workspace.workspace_database_id)?; + let mut conn = self.get_sqlite_connection(session.user_id)?; + let workspace = select_user_workspace(&session.workspace_id, &mut conn)?; + let id = Uuid::from_str(&workspace.database_storage_id)?; Ok(id) } @@ -104,7 +106,7 @@ impl AuthenticateUser { let session = self.get_session()?; let collab_db = self.database.get_collab_db(uid)?; let read_txn = collab_db.read_txn(); - Ok(read_txn.is_exist(uid, session.user_workspace.id.as_str(), object_id)) + Ok(read_txn.is_exist(uid, session.workspace_id.as_str(), object_id)) } pub fn set_session(&self, session: Option>) -> Result<(), FlowyError> { @@ -133,7 +135,7 @@ impl AuthenticateUser { self.set_session(Some(Arc::new(Session { user_id: session.user_id, user_uuid: session.user_uuid, - user_workspace, + workspace_id: user_workspace.id, }))) } diff --git a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs index c79d80bbf1..bc24b491e4 100644 --- a/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs +++ b/frontend/rust-lib/flowy-user/src/services/data_import/appflowy_data_import.rs @@ -1,4 +1,4 @@ -use crate::migrations::session_migration::migrate_session; +use crate::migrations::session_migration::{get_session_workspace, migrate_session}; use crate::services::data_import::importer::load_collab_by_object_ids; use crate::services::db::UserDBPath; @@ -51,6 +51,7 @@ pub(crate) struct ImportedFolder { pub container_name: Option, pub parent_view_id: Option, pub source: ImportedSource, + pub workspace_database_id: String, } #[derive(Clone)] @@ -81,6 +82,11 @@ pub(crate) fn prepare_import( let user_paths = UserPaths::new(path.to_string()); let other_store_preferences = Arc::new(KVStorePreferences::new(path)?); migrate_session("appflowy_session_cache", &other_store_preferences); + + let session_workspace = get_session_workspace(&other_store_preferences) + .ok_or(anyhow!("Can't find the session workspace"))?; + let workspace_database_id = session_workspace.workspace_database_id; + let imported_session = other_store_preferences .get_object::("appflowy_session_cache") .ok_or(anyhow!( @@ -105,7 +111,7 @@ pub(crate) fn prepare_import( let mut conn = imported_sqlite_db.get_connection()?; let imported_user_auth_type = select_user_profile( imported_session.user_id, - &imported_session.user_workspace.id, + &imported_session.workspace_id, &mut conn, ) .map(|v| v.auth_type) @@ -126,6 +132,7 @@ pub(crate) fn prepare_import( container_name: None, parent_view_id, source: ImportedSource::ExternalFolder, + workspace_database_id, }) } @@ -154,13 +161,13 @@ pub(crate) fn generate_import_data( imported_folder: ImportedFolder, ) -> anyhow::Result { info!( - "[AppflowyData]:importing workspace: {}:{}", - imported_folder.imported_session.user_workspace.name, - imported_folder.imported_session.user_workspace.id, + "[AppflowyData]:importing workspace: {}", + imported_folder.imported_session.workspace_id, ); - let workspace_id = current_session.user_workspace.id.clone(); - let imported_workspace_id = imported_folder.imported_session.user_workspace.id.clone(); + let workspace_id = current_session.workspace_id.clone(); + let imported_workspace_id = imported_folder.imported_session.workspace_id.clone(); let imported_session = imported_folder.imported_session.clone(); + let imported_workspace_database_id = imported_folder.workspace_database_id.clone(); let imported_collab_db = imported_folder.imported_collab_db.clone(); let imported_container_view_name = imported_folder.container_name.clone(); @@ -202,18 +209,18 @@ pub(crate) fn generate_import_data( // 2. workspace database views // 3. user awareness // So we remove these object ids from the list - let user_workspace_id = &imported_session.user_workspace.id; - let workspace_database_id = &imported_session.user_workspace.workspace_database_id; + let user_workspace_id = &imported_session.workspace_id; let user_awareness_id = user_awareness_object_id(&imported_session.user_uuid, user_workspace_id).to_string(); all_imported_object_ids.retain(|id| { - id != user_workspace_id && id != workspace_database_id && id != &user_awareness_id + id != user_workspace_id && id != &imported_workspace_database_id && id != &user_awareness_id }); // 2. mapping the workspace database ids if let Err(err) = mapping_workspace_database_ids( &mut old_to_new_id_map, &imported_session, + &imported_workspace_database_id, &imported_collab_db_read_txn, &mut database_view_ids_by_database_id, &mut database_object_ids, @@ -293,7 +300,7 @@ pub(crate) fn generate_import_data( for view_id in not_exist_parent_view_ids { if let Err(err) = create_empty_document_for_view( current_session.user_id, - ¤t_session.user_workspace.id, + ¤t_session.workspace_id, &view_id, current_collab_db_write_txn, ) { @@ -489,7 +496,7 @@ where write_collab_object( &collab, current_session.user_id, - current_session.user_workspace.id.as_str(), + current_session.workspace_id.as_str(), import_container_view_id, collab_write_txn, CollabType::Document, @@ -499,7 +506,7 @@ where let import_container_views = NestedChildViewBuilder::new( current_session.user_id, - current_session.user_workspace.id.clone(), + current_session.workspace_id.clone(), ) .with_view_id(import_container_view_id) .with_layout(ViewLayout::Document) @@ -514,6 +521,7 @@ where fn mapping_workspace_database_ids<'a, W>( old_to_new_id_map: &mut OldToNewIdMap, imported_session: &Session, + imported_session_workspace_database_id: &str, imported_collab_db_read_txn: &W, database_view_ids_by_database_id: &mut HashMap>, database_object_ids: &mut HashSet, @@ -524,20 +532,20 @@ where { let mut workspace_database_collab = Collab::new( imported_session.user_id, - &imported_session.user_workspace.workspace_database_id, + imported_session_workspace_database_id, "import_device", vec![], false, ); imported_collab_db_read_txn.load_doc_with_txn( imported_session.user_id, - &imported_session.user_workspace.id, - &imported_session.user_workspace.workspace_database_id, + &imported_session.workspace_id, + imported_session_workspace_database_id, &mut workspace_database_collab.transact_mut(), )?; let workspace_database = init_workspace_database( - &imported_session.user_workspace.workspace_database_id, + imported_session_workspace_database_id, workspace_database_collab, ); for database_meta_list in workspace_database.get_all_database_meta() { @@ -661,7 +669,7 @@ where write_collab_object( database_collab, session.user_id, - session.user_workspace.id.as_str(), + &session.workspace_id, &new_database_object_id, collab_write_txn, CollabType::Database, @@ -684,7 +692,7 @@ where }) .collect::>(); for gen_collab in gen_database_row_document_collabs { - write_gen_collab(&session.user_workspace.id, gen_collab, collab_write_txn); + write_gen_collab(&session.workspace_id, gen_collab, collab_write_txn); } // remove the database object ids from the object ids @@ -771,7 +779,7 @@ where .collect::>(); for gen_collab in gen_database_row_collabs { - write_gen_collab(&session.user_workspace.id, gen_collab, collab_write_txn); + write_gen_collab(&session.workspace_id, gen_collab, collab_write_txn); } } @@ -936,7 +944,7 @@ where { let mut imported_folder_collab = Collab::new( imported_session.user_id, - &imported_session.user_workspace.id, + &imported_session.workspace_id, "migrate_device", vec![], false, @@ -945,15 +953,15 @@ where imported_collab_db_read_txn .load_doc_with_txn( imported_session.user_id, - &imported_session.user_workspace.id, - &imported_session.user_workspace.id, + &imported_session.workspace_id, + &imported_session.workspace_id, &mut imported_folder_collab.transact_mut(), ) .map_err(|err| { PersistenceError::Internal(anyhow!( "[AppflowyData]: Can't load the user:{} folder:{}. {}", imported_session.user_id, - imported_session.user_workspace.id, + imported_session.workspace_id, err )) })?; @@ -964,7 +972,7 @@ where })?; let mut imported_folder_data = imported_folder - .get_folder_data(&imported_session.user_workspace.id) + .get_folder_data(&imported_session.workspace_id) .ok_or(PersistenceError::Internal(anyhow!( "[AppflowyData]: Can't read the folder data" )))?; @@ -1005,7 +1013,7 @@ where // replace the old parent view id of the workspace old_to_new_id_map.0.insert( - imported_session.user_workspace.id.clone(), + imported_session.workspace_id.clone(), root_view_id.to_string(), ); diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager.rs index 69894478ad..057519deaf 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager.rs @@ -128,11 +128,13 @@ impl UserManager { if let Ok(session) = self.get_session() { info!( - "Init user session: {}:{}, workspace: {}", - session.user_id, session.user_workspace.name, session.user_workspace.id + "Init user session: {}, workspace: {}", + session.user_id, session.workspace_id ); + let workspace_uuid = Uuid::parse_str(&session.workspace_id)?; + let mut conn = self.db_connection(session.user_id)?; + let auth_type = select_user_workspace_type(&session.workspace_id, &mut conn)?; - let auth_type = session.user_workspace.workspace_type; let uid = session.user_id; let token = self.token_from_auth_type(&auth_type)?; self @@ -158,11 +160,11 @@ impl UserManager { let weak_cloud_services = Arc::downgrade(&self.cloud_service); let weak_authenticate_user = Arc::downgrade(&self.authenticate_user); let weak_pool = Arc::downgrade(&self.db_pool(uid)?); + let workspace_id = session.workspace_id.clone(); let cloned_session = session.clone(); if let Some(mut token_state_rx) = self.cloud_service.subscribe_token_state() { event!(tracing::Level::DEBUG, "Listen token state change"); let user_uid = uid; - let workspace_id = session.user_workspace.id.clone(); tokio::spawn(async move { while let Some(token_state) = token_state_rx.next().await { debug!("Token state changed: {:?}", token_state); @@ -260,7 +262,7 @@ impl UserManager { .on_launch_if_authenticated( uid, &cloud_config, - &session.user_workspace, + &workspace_uuid, &self.authenticate_user.user_config.device_id, &auth_type, ) @@ -340,6 +342,7 @@ impl UserManager { self.prepare_user(&session).await; let latest_workspace = response.latest_workspace.clone(); + let workspace_id = Uuid::parse_str(&latest_workspace.id)?; let user_profile = UserProfile::from((&response, &auth_type)); self.save_auth_data(&response, auth_type, &session).await?; @@ -352,7 +355,7 @@ impl UserManager { .await .on_sign_in( user_profile.uid, - &latest_workspace, + &workspace_id, &self.authenticate_user.user_config.device_id, &auth_type, ) @@ -404,6 +407,7 @@ impl UserManager { .save_auth_data(&response, *auth_type, &new_session) .await?; let _ = self.initial_user_awareness(&new_session, auth_type).await; + let workspace_id = Uuid::parse_str(&new_session.workspace_id)?; self .user_status_callback .read() @@ -411,7 +415,7 @@ impl UserManager { .on_sign_up( response.is_new_user, new_user_profile, - &new_session.user_workspace, + &workspace_id, &self.authenticate_user.user_config.device_id, auth_type, ) @@ -493,7 +497,7 @@ impl UserManager { let session = self.get_session()?; upsert_user_profile_change( session.user_id, - &session.user_workspace.id, + &session.workspace_id, self.db_connection(session.user_id)?, changeset, )?; @@ -523,7 +527,7 @@ impl UserManager { self .authenticate_user .database - .backup(session.user_id, &session.user_workspace.id); + .backup(session.user_id, &session.workspace_id); } /// Fetches the user profile for the given user ID. @@ -627,7 +631,7 @@ impl UserManager { pub fn workspace_id(&self) -> Result { let session = self.get_session()?; - Ok(session.user_workspace.id.clone()) + Ok(session.workspace_id.clone()) } pub fn token(&self) -> Result, FlowyError> { @@ -758,7 +762,7 @@ impl UserManager { // Save the user profile change upsert_user_profile_change( user_update.uid, - &session.user_workspace.id, + &session.workspace_id, self.db_connection(user_update.uid)?, UserTableChangeset::from(user_update), )?; @@ -784,17 +788,6 @@ impl UserManager { .await?; } - // Save the old user workspace setting. - let mut conn = self - .authenticate_user - .database - .get_connection(old_user.session.user_id)?; - upsert_user_workspace( - old_user.session.user_id, - *auth_type, - old_user.session.user_workspace.clone(), - &mut conn, - )?; Ok(()) } } diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_history_user.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_history_user.rs index 188cc3c5ac..5ab8a62f8c 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_history_user.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_history_user.rs @@ -20,7 +20,7 @@ impl UserManager { let session = self.get_session().ok()?; let user_profile = self - .get_user_profile_from_disk(session.user_id, &session.user_workspace.id) + .get_user_profile_from_disk(session.user_id, &session.workspace_id) .await .ok()?; @@ -48,7 +48,7 @@ impl UserManager { "Anon user not found", ))?; let profile = self - .get_user_profile_from_disk(anon_session.user_id, &anon_session.user_workspace.id) + .get_user_profile_from_disk(anon_session.user_id, &anon_session.workspace_id) .await?; Ok(UserProfilePB::from(profile)) } diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs index 47826054bf..1edf4f393b 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_awareness.rs @@ -121,7 +121,7 @@ impl UserManager { session: &Session, auth_type: &AuthType, ) -> FlowyResult<()> { - let object_id = user_awareness_object_id(&session.user_uuid, &session.user_workspace.id); + let object_id = user_awareness_object_id(&session.user_uuid, &session.workspace_id); // Try to acquire mutable access to `is_loading_awareness`. // Thread-safety is ensured by DashMap @@ -162,7 +162,7 @@ impl UserManager { auth_type ); let collab_db = self.get_collab_db(session.user_id)?; - let workspace_id = session.user_workspace.workspace_id()?; + let workspace_id = Uuid::parse_str(&session.workspace_id)?; let doc_state = CollabPersistenceImpl::new(collab_db.clone(), session.user_id, workspace_id) .into_data_source(); @@ -227,7 +227,7 @@ impl UserManager { } }; - let workspace_id = session.user_workspace.workspace_id()?; + let workspace_id = Uuid::parse_str(&session.workspace_id)?; let create_awareness = if authenticator.is_local() { let doc_state = CollabPersistenceImpl::new(collab_db.clone(), session.user_id, workspace_id) @@ -289,7 +289,7 @@ impl UserManager { Ok(new_user_awareness) => { // Validate session before storing the awareness if let Ok(current_session) = authenticate_user.get_session() { - if current_session.user_workspace.id == session.user_workspace.id { + if current_session.workspace_id == session.workspace_id { if let Some(user_awareness) = user_awareness.upgrade() { info!("User awareness initialized successfully"); user_awareness.store(Some(new_user_awareness)); @@ -366,7 +366,7 @@ impl UserManager { info!("User awareness is not loaded when trying to access it"); let session = self.get_session()?; - let object_id = user_awareness_object_id(&session.user_uuid, &session.user_workspace.id); + let object_id = user_awareness_object_id(&session.user_uuid, &session.workspace_id); let is_loading = self .is_loading_awareness .get(&object_id) @@ -375,7 +375,7 @@ impl UserManager { if !is_loading { let user_profile = self - .get_user_profile_from_disk(session.user_id, &session.user_workspace.id) + .get_user_profile_from_disk(session.user_id, &session.workspace_id) .await?; self .initial_user_awareness(&session, &user_profile.workspace_auth_type) diff --git a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs index b78d635133..2dd99558a7 100644 --- a/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs +++ b/frontend/rust-lib/flowy-user/src/user_manager/manager_user_workspace.rs @@ -101,7 +101,7 @@ impl UserManager { collab_data: ImportedCollabData, ) -> Result<(), FlowyError> { let user = self - .get_user_profile_from_disk(current_session.user_id, ¤t_session.user_workspace.id) + .get_user_profile_from_disk(current_session.user_id, ¤t_session.workspace_id) .await?; let user_collab_db = self .get_collab_db(current_session.user_id)? @@ -109,12 +109,13 @@ impl UserManager { .ok_or_else(|| FlowyError::internal().with_context("Collab db not found"))?; let user_id = current_session.user_id; + let workspace_id = Uuid::parse_str(¤t_session.workspace_id)?; let weak_user_collab_db = Arc::downgrade(&user_collab_db); let weak_user_cloud_service = self.cloud_service.get_user_service()?; match upload_collab_objects_data( user_id, weak_user_collab_db, - ¤t_session.user_workspace.workspace_id()?, + &workspace_id, &user.workspace_auth_type, collab_data, weak_user_cloud_service, @@ -146,6 +147,7 @@ impl UserManager { container_name: None, parent_view_id: None, source: ImportedSource::AnonUser, + workspace_database_id: "".to_string(), }; self.perform_import(import_context).await?; Ok(())