Просмотр исходного кода

chore: sync document (#3653)

* chore: sync document

* chore: update collab rev

* chore: update collab rev
Nathan.fooo 1 год назад
Родитель
Сommit
77e7cbe9ec
57 измененных файлов с 401 добавлено и 214 удалено
  1. 8 1
      frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_user.dart
  2. 73 44
      frontend/appflowy_tauri/src-tauri/Cargo.lock
  3. 9 9
      frontend/appflowy_tauri/src-tauri/Cargo.toml
  4. 59 44
      frontend/rust-lib/Cargo.lock
  5. 9 9
      frontend/rust-lib/Cargo.toml
  6. 2 2
      frontend/rust-lib/collab-integrate/Cargo.toml
  7. 1 1
      frontend/rust-lib/collab-integrate/src/collab_builder.rs
  8. 2 2
      frontend/rust-lib/flowy-core/Cargo.toml
  9. 1 1
      frontend/rust-lib/flowy-core/src/integrate/collab_interact.rs
  10. 19 4
      frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs
  11. 6 2
      frontend/rust-lib/flowy-core/src/lib.rs
  12. 1 1
      frontend/rust-lib/flowy-database-deps/Cargo.toml
  13. 1 1
      frontend/rust-lib/flowy-database-deps/src/cloud.rs
  14. 1 1
      frontend/rust-lib/flowy-database2/Cargo.toml
  15. 1 1
      frontend/rust-lib/flowy-database2/src/manager.rs
  16. 1 1
      frontend/rust-lib/flowy-document2/Cargo.toml
  17. 1 1
      frontend/rust-lib/flowy-document2/src/manager.rs
  18. 1 1
      frontend/rust-lib/flowy-document2/src/reminder.rs
  19. 1 1
      frontend/rust-lib/flowy-folder2/Cargo.toml
  20. 1 1
      frontend/rust-lib/flowy-folder2/src/manager.rs
  21. 3 2
      frontend/rust-lib/flowy-server/Cargo.toml
  22. 33 5
      frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs
  23. 1 1
      frontend/rust-lib/flowy-server/src/af_cloud/impls/document.rs
  24. 1 1
      frontend/rust-lib/flowy-server/src/af_cloud/impls/folder.rs
  25. 3 11
      frontend/rust-lib/flowy-server/src/af_cloud/impls/user.rs
  26. 40 4
      frontend/rust-lib/flowy-server/src/af_cloud/server.rs
  27. 1 1
      frontend/rust-lib/flowy-server/src/local_server/impls/database.rs
  28. 1 1
      frontend/rust-lib/flowy-server/src/local_server/impls/user.rs
  29. 11 1
      frontend/rust-lib/flowy-server/src/server.rs
  30. 3 2
      frontend/rust-lib/flowy-server/src/supabase/api/collab_storage.rs
  31. 1 1
      frontend/rust-lib/flowy-server/src/supabase/api/database.rs
  32. 1 1
      frontend/rust-lib/flowy-server/src/supabase/api/document.rs
  33. 1 1
      frontend/rust-lib/flowy-server/src/supabase/api/folder.rs
  34. 1 1
      frontend/rust-lib/flowy-server/src/supabase/api/request.rs
  35. 1 1
      frontend/rust-lib/flowy-server/src/supabase/api/user.rs
  36. 1 1
      frontend/rust-lib/flowy-server/src/supabase/define.rs
  37. 1 1
      frontend/rust-lib/flowy-server/src/supabase/server.rs
  38. 1 1
      frontend/rust-lib/flowy-server/tests/supabase_test/database_test.rs
  39. 1 1
      frontend/rust-lib/flowy-server/tests/supabase_test/folder_test.rs
  40. 5 13
      frontend/rust-lib/flowy-server/tests/supabase_test/user_test.rs
  41. 1 1
      frontend/rust-lib/flowy-test/Cargo.toml
  42. 1 1
      frontend/rust-lib/flowy-test/tests/database/supabase_test/helper.rs
  43. 1 1
      frontend/rust-lib/flowy-test/tests/user/supabase_test/auth_test.rs
  44. 1 1
      frontend/rust-lib/flowy-user-deps/Cargo.toml
  45. 1 1
      frontend/rust-lib/flowy-user-deps/src/cloud.rs
  46. 20 8
      frontend/rust-lib/flowy-user-deps/src/entities.rs
  47. 2 1
      frontend/rust-lib/flowy-user/Cargo.toml
  48. 1 1
      frontend/rust-lib/flowy-user/src/entities/reminder.rs
  49. 1 0
      frontend/rust-lib/flowy-user/src/entities/user_profile.rs
  50. 10 0
      frontend/rust-lib/flowy-user/src/event_map.rs
  51. 44 14
      frontend/rust-lib/flowy-user/src/manager.rs
  52. 1 1
      frontend/rust-lib/flowy-user/src/migrations/sync_new_user.rs
  53. 1 1
      frontend/rust-lib/flowy-user/src/services/collab_interact.rs
  54. 2 2
      frontend/rust-lib/flowy-user/src/services/user_awareness.rs
  55. 3 0
      frontend/rust-lib/flowy-user/src/services/user_sql.rs
  56. 1 1
      frontend/rust-lib/flowy-user/src/services/user_workspace.rs
  57. 1 1
      frontend/scripts/tool/update_collab_source.sh

+ 8 - 1
frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar_user.dart

@@ -4,6 +4,7 @@ import 'package:appflowy/startup/startup.dart';
 import 'package:appflowy/workspace/application/menu/menu_user_bloc.dart';
 import 'package:appflowy/workspace/presentation/notifications/notification_button.dart';
 import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart';
+import 'package:appflowy_backend/log.dart';
 import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
 import 'package:appflowy/workspace/presentation/widgets/user_avatar.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
@@ -81,7 +82,13 @@ class SidebarUser extends StatelessWidget {
                     Navigator.of(dialogContext).pop();
                     await runAppFlowy();
                   },
-                  dismissDialog: () => Navigator.of(context).pop(),
+                  dismissDialog: () {
+                    if (Navigator.of(dialogContext).canPop()) {
+                      Navigator.of(dialogContext).pop();
+                    } else {
+                      Log.warn("Can't pop dialog context");
+                    }
+                  },
                   didOpenUser: () async {
                     // Pop the dialog using the dialog context
                     Navigator.of(dialogContext).pop();

+ 73 - 44
frontend/appflowy_tauri/src-tauri/Cargo.lock

@@ -454,7 +454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b"
 dependencies = [
  "borsh-derive",
- "hashbrown 0.13.2",
+ "hashbrown 0.12.3",
 ]
 
 [[package]]
@@ -762,12 +762,12 @@ dependencies = [
 [[package]]
 name = "client-api"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=926da91#926da912eab806e5b325e12103d341cea536aa2b"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
 dependencies = [
  "anyhow",
  "bytes",
  "collab",
- "collab-define",
+ "collab-entity",
  "database-entity",
  "futures-core",
  "futures-util",
@@ -776,6 +776,7 @@ dependencies = [
  "lib0",
  "mime",
  "parking_lot",
+ "realtime-entity",
  "reqwest",
  "scraper",
  "serde",
@@ -852,7 +853,7 @@ dependencies = [
 [[package]]
 name = "collab"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "anyhow",
  "async-trait",
@@ -871,15 +872,15 @@ dependencies = [
 [[package]]
 name = "collab-database"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "anyhow",
  "async-trait",
  "base64 0.21.2",
  "chrono",
  "collab",
- "collab-define",
  "collab-derive",
+ "collab-entity",
  "collab-persistence",
  "collab-plugins",
  "lazy_static",
@@ -898,24 +899,10 @@ dependencies = [
  "uuid",
 ]
 
-[[package]]
-name = "collab-define"
-version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
-dependencies = [
- "anyhow",
- "bytes",
- "collab",
- "serde",
- "serde_json",
- "serde_repr",
- "uuid",
-]
-
 [[package]]
 name = "collab-derive"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -927,7 +914,7 @@ dependencies = [
 [[package]]
 name = "collab-document"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "anyhow",
  "collab",
@@ -944,10 +931,24 @@ dependencies = [
  "tracing",
 ]
 
+[[package]]
+name = "collab-entity"
+version = "0.1.0"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
+dependencies = [
+ "anyhow",
+ "bytes",
+ "collab",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "uuid",
+]
+
 [[package]]
 name = "collab-folder"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "anyhow",
  "chrono",
@@ -972,8 +973,8 @@ dependencies = [
  "async-trait",
  "collab",
  "collab-database",
- "collab-define",
  "collab-document",
+ "collab-entity",
  "collab-folder",
  "collab-persistence",
  "collab-plugins",
@@ -989,7 +990,7 @@ dependencies = [
 [[package]]
 name = "collab-persistence"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "async-trait",
  "bincode",
@@ -1010,13 +1011,13 @@ dependencies = [
 [[package]]
 name = "collab-plugins"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "anyhow",
  "async-trait",
  "bytes",
  "collab",
- "collab-define",
+ "collab-entity",
  "collab-persistence",
  "futures-util",
  "lib0",
@@ -1037,11 +1038,11 @@ dependencies = [
 [[package]]
 name = "collab-user"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "anyhow",
  "collab",
- "collab-define",
+ "collab-entity",
  "parking_lot",
  "serde",
  "serde_json",
@@ -1290,7 +1291,7 @@ dependencies = [
  "cssparser-macros",
  "dtoa-short",
  "itoa 1.0.6",
- "phf 0.8.0",
+ "phf 0.11.2",
  "smallvec",
 ]
 
@@ -1436,11 +1437,11 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
 [[package]]
 name = "database-entity"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=926da91#926da912eab806e5b325e12103d341cea536aa2b"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
 dependencies = [
  "anyhow",
  "chrono",
- "collab-define",
+ "collab-entity",
  "serde",
  "serde_json",
  "sqlx",
@@ -1914,7 +1915,7 @@ dependencies = [
  "bytes",
  "client-api",
  "collab",
- "collab-define",
+ "collab-entity",
  "collab-integrate",
  "collab-plugins",
  "diesel",
@@ -1954,7 +1955,7 @@ name = "flowy-database-deps"
 version = "0.1.0"
 dependencies = [
  "anyhow",
- "collab-define",
+ "collab-entity",
  "flowy-error",
  "lib-infra",
 ]
@@ -1971,7 +1972,7 @@ dependencies = [
  "chrono-tz 0.8.2",
  "collab",
  "collab-database",
- "collab-define",
+ "collab-entity",
  "collab-integrate",
  "csv",
  "dashmap",
@@ -2052,8 +2053,8 @@ dependencies = [
  "anyhow",
  "bytes",
  "collab",
- "collab-define",
  "collab-document",
+ "collab-entity",
  "collab-integrate",
  "flowy-codegen",
  "flowy-derive",
@@ -2133,7 +2134,7 @@ dependencies = [
  "bytes",
  "chrono",
  "collab",
- "collab-define",
+ "collab-entity",
  "collab-folder",
  "collab-integrate",
  "flowy-codegen",
@@ -2178,8 +2179,8 @@ dependencies = [
  "chrono",
  "client-api",
  "collab",
- "collab-define",
  "collab-document",
+ "collab-entity",
  "collab-plugins",
  "config",
  "flowy-database-deps",
@@ -2206,6 +2207,7 @@ dependencies = [
  "thiserror",
  "tokio",
  "tokio-retry",
+ "tokio-stream",
  "tokio-util",
  "tracing",
  "url",
@@ -2275,8 +2277,8 @@ dependencies = [
  "chrono",
  "collab",
  "collab-database",
- "collab-define",
  "collab-document",
+ "collab-entity",
  "collab-folder",
  "collab-integrate",
  "collab-user",
@@ -2305,6 +2307,7 @@ dependencies = [
  "strum",
  "strum_macros 0.25.2",
  "tokio",
+ "tokio-stream",
  "tracing",
  "unicode-segmentation",
  "uuid",
@@ -2317,7 +2320,7 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "chrono",
- "collab-define",
+ "collab-entity",
  "flowy-error",
  "lib-infra",
  "serde",
@@ -2775,7 +2778,7 @@ dependencies = [
 [[package]]
 name = "gotrue"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=926da91#926da912eab806e5b325e12103d341cea536aa2b"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
 dependencies = [
  "anyhow",
  "futures-util",
@@ -2791,7 +2794,7 @@ dependencies = [
 [[package]]
 name = "gotrue-entity"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=926da91#926da912eab806e5b325e12103d341cea536aa2b"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
 dependencies = [
  "anyhow",
  "reqwest",
@@ -3224,7 +3227,7 @@ dependencies = [
 [[package]]
 name = "infra"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=926da91#926da912eab806e5b325e12103d341cea536aa2b"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
 dependencies = [
  "anyhow",
  "reqwest",
@@ -4265,6 +4268,7 @@ version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
 dependencies = [
+ "phf_macros 0.11.2",
  "phf_shared 0.11.2",
 ]
 
@@ -4356,6 +4360,19 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "phf_macros"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
+dependencies = [
+ "phf_generator 0.11.2",
+ "phf_shared 0.11.2",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.29",
+]
+
 [[package]]
 name = "phf_shared"
 version = "0.8.0"
@@ -4856,6 +4873,18 @@ dependencies = [
  "num_cpus",
 ]
 
+[[package]]
+name = "realtime-entity"
+version = "0.1.0"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
+dependencies = [
+ "bytes",
+ "collab",
+ "collab-entity",
+ "serde",
+ "serde_json",
+]
+
 [[package]]
 name = "redox_syscall"
 version = "0.1.57"
@@ -5569,7 +5598,7 @@ dependencies = [
 [[package]]
 name = "shared_entity"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=926da91#926da912eab806e5b325e12103d341cea536aa2b"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
 dependencies = [
  "anyhow",
  "database-entity",

+ 9 - 9
frontend/appflowy_tauri/src-tauri/Cargo.toml

@@ -38,7 +38,7 @@ custom-protocol = ["tauri/custom-protocol"]
 # Run the script:
 # scripts/tool/update_client_api_rev.sh  new_rev_id
 # ⚠️⚠️⚠️️
-client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "926da91" }
+client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6faefb0" }
 # Please use the following script to update collab.
 # Working directory: frontend
 #
@@ -48,14 +48,14 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "926
 # To switch to the local path, run:
 # scripts/tool/update_collab_source.sh
 # ⚠️⚠️⚠️️
-collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-define = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
+collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
 
 
 

+ 59 - 44
frontend/rust-lib/Cargo.lock

@@ -461,7 +461,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b"
 dependencies = [
  "borsh-derive",
- "hashbrown 0.13.2",
+ "hashbrown 0.12.3",
 ]
 
 [[package]]
@@ -660,12 +660,12 @@ dependencies = [
 [[package]]
 name = "client-api"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=926da91#926da912eab806e5b325e12103d341cea536aa2b"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
 dependencies = [
  "anyhow",
  "bytes",
  "collab",
- "collab-define",
+ "collab-entity",
  "database-entity",
  "futures-core",
  "futures-util",
@@ -674,6 +674,7 @@ dependencies = [
  "lib0",
  "mime",
  "parking_lot",
+ "realtime-entity",
  "reqwest",
  "scraper",
  "serde",
@@ -719,7 +720,7 @@ dependencies = [
 [[package]]
 name = "collab"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "anyhow",
  "async-trait",
@@ -738,15 +739,15 @@ dependencies = [
 [[package]]
 name = "collab-database"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "anyhow",
  "async-trait",
  "base64 0.21.3",
  "chrono",
  "collab",
- "collab-define",
  "collab-derive",
+ "collab-entity",
  "collab-persistence",
  "collab-plugins",
  "lazy_static",
@@ -765,24 +766,10 @@ dependencies = [
  "uuid",
 ]
 
-[[package]]
-name = "collab-define"
-version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
-dependencies = [
- "anyhow",
- "bytes",
- "collab",
- "serde",
- "serde_json",
- "serde_repr",
- "uuid",
-]
-
 [[package]]
 name = "collab-derive"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -794,7 +781,7 @@ dependencies = [
 [[package]]
 name = "collab-document"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "anyhow",
  "collab",
@@ -811,10 +798,24 @@ dependencies = [
  "tracing",
 ]
 
+[[package]]
+name = "collab-entity"
+version = "0.1.0"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
+dependencies = [
+ "anyhow",
+ "bytes",
+ "collab",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "uuid",
+]
+
 [[package]]
 name = "collab-folder"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "anyhow",
  "chrono",
@@ -839,8 +840,8 @@ dependencies = [
  "async-trait",
  "collab",
  "collab-database",
- "collab-define",
  "collab-document",
+ "collab-entity",
  "collab-folder",
  "collab-persistence",
  "collab-plugins",
@@ -856,7 +857,7 @@ dependencies = [
 [[package]]
 name = "collab-persistence"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "async-trait",
  "bincode",
@@ -877,13 +878,13 @@ dependencies = [
 [[package]]
 name = "collab-plugins"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "anyhow",
  "async-trait",
  "bytes",
  "collab",
- "collab-define",
+ "collab-entity",
  "collab-persistence",
  "futures-util",
  "lib0",
@@ -904,11 +905,11 @@ dependencies = [
 [[package]]
 name = "collab-user"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=82975da#82975da119a0c9d0e8b70585966bb89ed6c97cd3"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=2f5734ae#2f5734ae9e58efd611383b78cd9068d514643e75"
 dependencies = [
  "anyhow",
  "collab",
- "collab-define",
+ "collab-entity",
  "parking_lot",
  "serde",
  "serde_json",
@@ -1263,11 +1264,11 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
 [[package]]
 name = "database-entity"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=926da91#926da912eab806e5b325e12103d341cea536aa2b"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
 dependencies = [
  "anyhow",
  "chrono",
- "collab-define",
+ "collab-entity",
  "serde",
  "serde_json",
  "sqlx",
@@ -1688,7 +1689,7 @@ dependencies = [
  "bytes",
  "client-api",
  "collab",
- "collab-define",
+ "collab-entity",
  "collab-integrate",
  "collab-plugins",
  "console-subscriber",
@@ -1729,7 +1730,7 @@ name = "flowy-database-deps"
 version = "0.1.0"
 dependencies = [
  "anyhow",
- "collab-define",
+ "collab-entity",
  "flowy-error",
  "lib-infra",
 ]
@@ -1746,7 +1747,7 @@ dependencies = [
  "chrono-tz",
  "collab",
  "collab-database",
- "collab-define",
+ "collab-entity",
  "collab-integrate",
  "csv",
  "dashmap",
@@ -1828,8 +1829,8 @@ dependencies = [
  "anyhow",
  "bytes",
  "collab",
- "collab-define",
  "collab-document",
+ "collab-entity",
  "collab-integrate",
  "flowy-codegen",
  "flowy-derive",
@@ -1912,7 +1913,7 @@ dependencies = [
  "bytes",
  "chrono",
  "collab",
- "collab-define",
+ "collab-entity",
  "collab-folder",
  "collab-integrate",
  "flowy-codegen",
@@ -1960,8 +1961,8 @@ dependencies = [
  "chrono",
  "client-api",
  "collab",
- "collab-define",
  "collab-document",
+ "collab-entity",
  "collab-plugins",
  "config",
  "dotenv",
@@ -1989,6 +1990,7 @@ dependencies = [
  "thiserror",
  "tokio",
  "tokio-retry",
+ "tokio-stream",
  "tokio-util",
  "tracing",
  "tracing-subscriber 0.3.17",
@@ -2064,8 +2066,8 @@ dependencies = [
  "bytes",
  "collab",
  "collab-database",
- "collab-define",
  "collab-document",
+ "collab-entity",
  "collab-folder",
  "collab-plugins",
  "dotenv",
@@ -2110,8 +2112,8 @@ dependencies = [
  "chrono",
  "collab",
  "collab-database",
- "collab-define",
  "collab-document",
+ "collab-entity",
  "collab-folder",
  "collab-integrate",
  "collab-user",
@@ -2146,6 +2148,7 @@ dependencies = [
  "strum",
  "strum_macros 0.25.2",
  "tokio",
+ "tokio-stream",
  "tracing",
  "unicode-segmentation",
  "uuid",
@@ -2158,7 +2161,7 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "chrono",
- "collab-define",
+ "collab-entity",
  "flowy-error",
  "lib-infra",
  "serde",
@@ -2437,7 +2440,7 @@ dependencies = [
 [[package]]
 name = "gotrue"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=926da91#926da912eab806e5b325e12103d341cea536aa2b"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
 dependencies = [
  "anyhow",
  "futures-util",
@@ -2453,7 +2456,7 @@ dependencies = [
 [[package]]
 name = "gotrue-entity"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=926da91#926da912eab806e5b325e12103d341cea536aa2b"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
 dependencies = [
  "anyhow",
  "reqwest",
@@ -2811,7 +2814,7 @@ dependencies = [
 [[package]]
 name = "infra"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=926da91#926da912eab806e5b325e12103d341cea536aa2b"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
 dependencies = [
  "anyhow",
  "reqwest",
@@ -4199,6 +4202,18 @@ dependencies = [
  "rand_core 0.3.1",
 ]
 
+[[package]]
+name = "realtime-entity"
+version = "0.1.0"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
+dependencies = [
+ "bytes",
+ "collab",
+ "collab-entity",
+ "serde",
+ "serde_json",
+]
+
 [[package]]
 name = "redox_syscall"
 version = "0.1.57"
@@ -4811,7 +4826,7 @@ dependencies = [
 [[package]]
 name = "shared_entity"
 version = "0.1.0"
-source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=926da91#926da912eab806e5b325e12103d341cea536aa2b"
+source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6faefb0#6faefb083fe0a127045ec57431f126e499f4a687"
 dependencies = [
  "anyhow",
  "database-entity",

+ 9 - 9
frontend/rust-lib/Cargo.toml

@@ -82,7 +82,7 @@ incremental = false
 # Run the script:
 # scripts/tool/update_client_api_rev.sh  new_rev_id
 # ⚠️⚠️⚠️️
-client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "926da91" }
+client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6faefb0" }
 # Please use the following script to update collab.
 # Working directory: frontend
 #
@@ -92,11 +92,11 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "926
 # To switch to the local path, run:
 # scripts/tool/update_collab_source.sh
 # ⚠️⚠️⚠️️
-collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-define = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
-collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "82975da" }
+collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }
+collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "2f5734ae" }

+ 2 - 2
frontend/rust-lib/collab-integrate/Cargo.toml

@@ -12,7 +12,7 @@ collab-folder = { version = "0.1.0" }
 collab-database = { version = "0.1.0" }
 collab-plugins = { version = "0.1.0" }
 collab-document = { version = "0.1.0" }
-collab-define = { version = "0.1.0" }
+collab-entity = { version = "0.1.0" }
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
 anyhow = "1.0"
@@ -26,5 +26,5 @@ lib-infra = { path = "../../../shared-lib/lib-infra" }
 [features]
 default = []
 supabase_integrate = ["collab-plugins/postgres_storage_plugin", "collab-plugins/rocksdb_plugin"]
-appflowy_cloud_integrate = ["collab-plugins/sync_plugin", "collab-plugins/rocksdb_plugin"]
+appflowy_cloud_integrate = ["collab-plugins/rocksdb_plugin"]
 snapshot_plugin = ["collab-plugins/snapshot_plugin"]

+ 1 - 1
frontend/rust-lib/collab-integrate/src/collab_builder.rs

@@ -5,7 +5,7 @@ use anyhow::Error;
 use async_trait::async_trait;
 use collab::core::collab::{CollabRawData, MutexCollab};
 use collab::preclude::{CollabBuilder, CollabPlugin};
-use collab_define::{CollabObject, CollabType};
+use collab_entity::{CollabObject, CollabType};
 use collab_persistence::kv::rocks_kv::RocksCollabDB;
 use collab_plugins::cloud_storage::network_state::{CollabNetworkReachability, CollabNetworkState};
 use collab_plugins::local_storage::rocksdb::RocksdbDiskPlugin;

+ 2 - 2
frontend/rust-lib/flowy-core/Cargo.toml

@@ -25,8 +25,8 @@ flowy-config = { workspace = true }
 flowy-date = { workspace = true }
 collab-integrate = { workspace = true, features = ["supabase_integrate", "appflowy_cloud_integrate", "snapshot_plugin"] }
 flowy-ai = { workspace = true }
-collab-define = { version = "0.1.0" }
-collab-plugins = { version = "0.1.0", features = ["sync_plugin"] }
+collab-entity = { version = "0.1.0" }
+collab-plugins = { version = "0.1.0" }
 collab = { version = "0.1.0" }
 diesel = { version = "1.4.8", features = ["sqlite"] }
 uuid = { version = "1.3.3", features = ["v4"] }

+ 1 - 1
frontend/rust-lib/flowy-core/src/integrate/collab_interact.rs

@@ -1,4 +1,4 @@
-use collab_define::reminder::Reminder;
+use collab_entity::reminder::Reminder;
 use std::convert::TryFrom;
 use std::sync::Weak;
 

+ 19 - 4
frontend/rust-lib/flowy-core/src/integrate/trait_impls.rs

@@ -1,11 +1,13 @@
 use std::sync::Arc;
+use std::time::Duration;
 
 use anyhow::Error;
 use bytes::Bytes;
-use client_api::collab_sync::{SinkConfig, SyncObject, SyncPlugin};
+use client_api::collab_sync::{SinkConfig, SinkStrategy, SyncObject, SyncPlugin};
 use collab::core::origin::{CollabClient, CollabOrigin};
 use collab::preclude::CollabPlugin;
-use collab_define::CollabType;
+use collab_entity::CollabType;
+use tokio_stream::wrappers::WatchStream;
 
 use collab_integrate::collab_builder::{CollabPluginContext, CollabSource, CollabStorageProvider};
 use collab_integrate::postgres::SupabaseDBPlugin;
@@ -19,7 +21,7 @@ use flowy_folder_deps::cloud::{FolderCloudService, FolderData, FolderSnapshot, W
 use flowy_storage::{FileStorageService, StorageObject};
 use flowy_user::event_map::UserCloudServiceProvider;
 use flowy_user_deps::cloud::UserCloudService;
-use flowy_user_deps::entities::AuthType;
+use flowy_user_deps::entities::{AuthType, UserTokenState};
 use lib_infra::future::{to_fut, Fut, FutureResult};
 
 use crate::integrate::server::{ServerProvider, ServerType, SERVER_PROVIDER_TYPE_KEY};
@@ -51,6 +53,17 @@ impl FileStorageService for ServerProvider {
 }
 
 impl UserCloudServiceProvider for ServerProvider {
+  fn set_token(&self, token: &str) -> Result<(), FlowyError> {
+    let server = self.get_server(&self.get_server_type())?;
+    server.set_token(token)?;
+    Ok(())
+  }
+
+  fn subscribe_token_state(&self) -> Option<WatchStream<UserTokenState>> {
+    let server = self.get_server(&self.get_server_type()).ok()?;
+    server.subscribe_token_state()
+  }
+
   fn set_enable_sync(&self, uid: i64, enable_sync: bool) {
     match self.get_server(&self.get_server_type()) {
       Ok(server) => {
@@ -281,7 +294,9 @@ impl CollabStorageProvider for ServerProvider {
                 ));
                 let sync_object = SyncObject::from(collab_object);
                 let (sink, stream) = (channel.sink(), channel.stream());
-                let sink_config = SinkConfig::new().with_timeout(6);
+                let sink_config = SinkConfig::new()
+                  .send_timeout(6)
+                  .with_strategy(SinkStrategy::FixInterval(Duration::from_secs(2)));
                 let sync_plugin = SyncPlugin::new(
                   origin,
                   sync_object,

+ 6 - 2
frontend/rust-lib/flowy-core/src/lib.rs

@@ -5,6 +5,7 @@ use std::time::Duration;
 use std::{fmt, sync::Arc};
 
 use tokio::sync::RwLock;
+use tracing::error;
 
 use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabSource};
 use flowy_database2::DatabaseManager;
@@ -179,9 +180,12 @@ impl AppFlowyCore {
     let cloned_user_session = Arc::downgrade(&user_manager);
     runtime.block_on(async move {
       if let Some(user_session) = cloned_user_session.upgrade() {
-        user_session
+        if let Err(err) = user_session
           .init(user_status_callback, collab_interact_impl)
-          .await;
+          .await
+        {
+          error!("Init user failed: {}", err)
+        }
       }
     });
 

+ 1 - 1
frontend/rust-lib/flowy-database-deps/Cargo.toml

@@ -8,5 +8,5 @@ edition = "2021"
 [dependencies]
 lib-infra = { path = "../../../shared-lib/lib-infra" }
 flowy-error = { workspace = true }
-collab-define = { version = "0.1.0" }
+collab-entity = { version = "0.1.0" }
 anyhow = "1.0.71"

+ 1 - 1
frontend/rust-lib/flowy-database-deps/src/cloud.rs

@@ -1,7 +1,7 @@
 use std::collections::HashMap;
 
 use anyhow::Error;
-use collab_define::CollabType;
+use collab_entity::CollabType;
 
 use lib_infra::future::FutureResult;
 

+ 1 - 1
frontend/rust-lib/flowy-database2/Cargo.toml

@@ -8,7 +8,7 @@ edition = "2021"
 [dependencies]
 collab = { version = "0.1.0" }
 collab-database = { version = "0.1.0" }
-collab-define = { version = "0.1.0" }
+collab-entity = { version = "0.1.0" }
 collab-integrate = { workspace = true }
 flowy-database-deps = { workspace = true }
 

+ 1 - 1
frontend/rust-lib/flowy-database2/src/manager.rs

@@ -10,7 +10,7 @@ use collab_database::user::{
   WorkspaceDatabase,
 };
 use collab_database::views::{CreateDatabaseParams, CreateViewParams, DatabaseLayout};
-use collab_define::CollabType;
+use collab_entity::CollabType;
 use futures::executor::block_on;
 use tokio::sync::RwLock;
 use tracing::{instrument, trace};

+ 1 - 1
frontend/rust-lib/flowy-document2/Cargo.toml

@@ -8,7 +8,7 @@ edition = "2021"
 [dependencies]
 collab = { version = "0.1.0" }
 collab-document = { version = "0.1.0" }
-collab-define = { version = "0.1.0" }
+collab-entity = { version = "0.1.0" }
 collab-integrate = { workspace = true }
 flowy-document-deps = { workspace = true }
 flowy-storage = { workspace = true }

+ 1 - 1
frontend/rust-lib/flowy-document2/src/manager.rs

@@ -2,11 +2,11 @@ use std::sync::Weak;
 use std::{collections::HashMap, sync::Arc};
 
 use collab::core::collab::MutexCollab;
-use collab_define::CollabType;
 use collab_document::blocks::DocumentData;
 use collab_document::document::Document;
 use collab_document::document_data::default_document_data;
 use collab_document::YrsDocAction;
+use collab_entity::CollabType;
 use parking_lot::RwLock;
 use tracing::instrument;
 

+ 1 - 1
frontend/rust-lib/flowy-document2/src/reminder.rs

@@ -1,4 +1,4 @@
-use collab_define::reminder::Reminder;
+use collab_entity::reminder::Reminder;
 use serde::{Deserialize, Serialize};
 use serde_json::json;
 

+ 1 - 1
frontend/rust-lib/flowy-folder2/Cargo.toml

@@ -8,7 +8,7 @@ edition = "2021"
 [dependencies]
 collab = { version = "0.1.0" }
 collab-folder = { version = "0.1.0" }
-collab-define = { version = "0.1.0" }
+collab-entity = { version = "0.1.0" }
 collab-integrate = { workspace = true }
 flowy-folder-deps = { workspace = true }
 

+ 1 - 1
frontend/rust-lib/flowy-folder2/src/manager.rs

@@ -4,7 +4,7 @@ use std::sync::{Arc, Weak};
 
 use collab::core::collab::{CollabRawData, MutexCollab};
 use collab::core::collab_state::SyncState;
-use collab_define::CollabType;
+use collab_entity::CollabType;
 use collab_folder::core::{
   FavoritesInfo, Folder, FolderData, FolderNotify, TrashChange, TrashChangeReceiver, TrashInfo,
   View, ViewChange, ViewChangeReceiver, ViewLayout, ViewUpdate, Workspace,

+ 3 - 2
frontend/rust-lib/flowy-server/Cargo.toml

@@ -25,9 +25,9 @@ anyhow = "1.0"
 uuid = { version = "1.3.3", features = ["v4"] }
 chrono = { version = "0.4.31", default-features = false, features = ["clock"] }
 collab = { version = "0.1.0" }
-collab-plugins = { version = "0.1.0", features = ["sync_plugin"] }
+collab-plugins = { version = "0.1.0"}
 collab-document = { version = "0.1.0" }
-collab-define = { version = "0.1.0" }
+collab-entity = { version = "0.1.0" }
 hex = "0.4.3"
 postgrest = "1.0"
 lib-infra = { path = "../../../shared-lib/lib-infra" }
@@ -42,6 +42,7 @@ flowy-storage = { workspace = true }
 mime_guess = "2.0"
 url = "2.4"
 tokio-util = "0.7"
+tokio-stream = { version = "0.1.14", features = ["sync"] }
 client-api = { version = "0.1.0", features = ["collab-sync"] }
 
 [dev-dependencies]

+ 33 - 5
frontend/rust-lib/flowy-server/src/af_cloud/impls/database.rs

@@ -1,7 +1,9 @@
 use anyhow::Error;
-use client_api::entity::QueryCollabParams;
+use client_api::entity::QueryCollabResult::{Failed, Success};
+use client_api::entity::{BatchQueryCollabParams, QueryCollabParams};
 use client_api::error::ErrorCode::RecordNotFound;
-use collab_define::CollabType;
+use collab_entity::CollabType;
+use tracing::error;
 
 use flowy_database_deps::cloud::{
   CollabObjectUpdate, CollabObjectUpdateByOid, DatabaseCloudService, DatabaseSnapshot,
@@ -43,10 +45,36 @@ where
 
   fn batch_get_collab_updates(
     &self,
-    _object_ids: Vec<String>,
-    _object_ty: CollabType,
+    object_ids: Vec<String>,
+    object_ty: CollabType,
   ) -> FutureResult<CollabObjectUpdateByOid, Error> {
-    FutureResult::new(async move { Ok(CollabObjectUpdateByOid::default()) })
+    let try_get_client = self.0.try_get_client();
+    FutureResult::new(async move {
+      let client = try_get_client?;
+      let params = BatchQueryCollabParams(
+        object_ids
+          .into_iter()
+          .map(|object_id| QueryCollabParams {
+            object_id,
+            collab_type: object_ty.clone(),
+          })
+          .collect(),
+      );
+      let results = client.batch_get_collab(params).await?;
+      Ok(
+        results
+          .0
+          .into_iter()
+          .flat_map(|(object_id, result)| match result {
+            Success { blob } => Some((object_id, vec![blob])),
+            Failed { error } => {
+              error!("Failed to get {} update: {}", object_id, error);
+              None
+            },
+          })
+          .collect::<CollabObjectUpdateByOid>(),
+      )
+    })
   }
 
   fn get_collab_snapshots(

+ 1 - 1
frontend/rust-lib/flowy-server/src/af_cloud/impls/document.rs

@@ -1,8 +1,8 @@
 use anyhow::Error;
 use client_api::entity::QueryCollabParams;
 use collab::core::origin::CollabOrigin;
-use collab_define::CollabType;
 use collab_document::document::Document;
+use collab_entity::CollabType;
 
 use flowy_document_deps::cloud::*;
 use flowy_error::FlowyError;

+ 1 - 1
frontend/rust-lib/flowy-server/src/af_cloud/impls/folder.rs

@@ -1,7 +1,7 @@
 use anyhow::Error;
 use client_api::entity::QueryCollabParams;
 use collab::core::origin::CollabOrigin;
-use collab_define::CollabType;
+use collab_entity::CollabType;
 
 use flowy_error::FlowyError;
 use flowy_folder_deps::cloud::{Folder, FolderCloudService, FolderData, FolderSnapshot, Workspace};

+ 3 - 11
frontend/rust-lib/flowy-server/src/af_cloud/impls/user.rs

@@ -6,7 +6,7 @@ use client_api::entity::dto::UserUpdateParams;
 use client_api::entity::{
   AFUserProfileView, AFWorkspace, AFWorkspaces, InsertCollabParams, OAuthProvider,
 };
-use collab_define::CollabObject;
+use collab_entity::CollabObject;
 
 use flowy_error::{ErrorCode, FlowyError};
 use flowy_user_deps::cloud::UserCloudService;
@@ -113,7 +113,7 @@ where
       Ok(Some(UserProfile {
         email: profile.email.unwrap_or("".to_string()),
         name: profile.name.unwrap_or("".to_string()),
-        token: token_from_client(client).await.unwrap_or("".to_string()),
+        token: client.get_token()?,
         icon_url: "".to_owned(),
         openai_key: "".to_owned(),
         stability_ai_key: "".to_owned(),
@@ -141,7 +141,6 @@ where
     FutureResult::new(async move {
       // from params
       let token = credential.token.ok_or(anyhow!("expecting token"))?;
-      let uuid = credential.uuid.ok_or(anyhow!("expecting uuid"))?;
       let uid = credential.uid.ok_or(anyhow!("expecting uid"))?;
 
       // from cloud
@@ -150,9 +149,6 @@ where
       let client_token = client.access_token()?;
 
       // compare and check
-      if uuid != profile.uuid.ok_or(anyhow!("expecting uuid"))?.to_string() {
-        return Err(anyhow!("uuid mismatch"));
-      }
       if uid != profile.uid.ok_or(anyhow!("expecting uid"))? {
         return Err(anyhow!("uid mismatch"));
       }
@@ -252,17 +248,13 @@ pub async fn user_sign_in_with_url(
     latest_workspace,
     user_workspaces,
     email: profile.email,
-    token: token_from_client(client.clone()).await,
+    token: Some(client.get_token()?),
     device_id: params.device_id,
     encryption_type,
     is_new_user,
   })
 }
 
-async fn token_from_client(client: Arc<AFCloudClient>) -> Option<String> {
-  client.access_token().ok()
-}
-
 fn encryption_type_from_profile(profile: &AFUserProfileView) -> EncryptionType {
   match &profile.encryption_sign {
     Some(e) => EncryptionType::SelfEncryption(e.to_string()),

+ 40 - 4
frontend/rust-lib/flowy-server/src/af_cloud/server.rs

@@ -7,7 +7,9 @@ use client_api::ws::{
   BusinessID, WSClient, WSClientConfig, WSConnectStateReceiver, WebSocketChannel,
 };
 use client_api::Client;
-use tracing::info;
+use tokio::sync::watch;
+use tokio_stream::wrappers::WatchStream;
+use tracing::{error, info};
 
 use flowy_database_deps::cloud::DatabaseCloudService;
 use flowy_document_deps::cloud::DocumentCloudService;
@@ -16,6 +18,7 @@ use flowy_folder_deps::cloud::FolderCloudService;
 use flowy_server_config::af_cloud_config::AFCloudConfiguration;
 use flowy_storage::FileStorageService;
 use flowy_user_deps::cloud::UserCloudService;
+use flowy_user_deps::entities::UserTokenState;
 use lib_infra::future::FutureResult;
 
 use crate::af_cloud::impls::{
@@ -42,15 +45,14 @@ impl AFCloudServer {
     enable_sync: bool,
     device_id: Arc<parking_lot::RwLock<String>>,
   ) -> Self {
-    let api_client =
-      client_api::Client::new(&config.base_url, &config.ws_base_url, &config.gotrue_url);
+    let api_client = AFCloudClient::new(&config.base_url, &config.ws_base_url, &config.gotrue_url);
     let token_state_rx = api_client.subscribe_token_state();
     let enable_sync = AtomicBool::new(enable_sync);
 
     let ws_client = WSClient::new(WSClientConfig {
       buffer_capacity: 100,
       ping_per_secs: 8,
-      retry_connect_per_pings: 5,
+      retry_connect_per_pings: 6,
     });
     let ws_client = Arc::new(ws_client);
     let api_client = Arc::new(api_client);
@@ -75,6 +77,40 @@ impl AFCloudServer {
 }
 
 impl AppFlowyServer for AFCloudServer {
+  fn set_token(&self, token: &str) -> Result<(), Error> {
+    self
+      .client
+      .set_token(token)
+      .map_err(|err| Error::new(FlowyError::unauthorized().with_context(err)))
+  }
+
+  fn subscribe_token_state(&self) -> Option<WatchStream<UserTokenState>> {
+    let mut token_state_rx = self.client.subscribe_token_state();
+    let (watch_tx, watch_rx) = watch::channel(UserTokenState::Invalid);
+    let weak_client = Arc::downgrade(&self.client);
+    tokio::spawn(async move {
+      while let Ok(token_state) = token_state_rx.recv().await {
+        if let Some(client) = weak_client.upgrade() {
+          match token_state {
+            TokenState::Refresh => match client.get_token() {
+              Ok(token) => {
+                let _ = watch_tx.send(UserTokenState::Refresh { token });
+              },
+              Err(err) => {
+                error!("Failed to get token after token state changed: {}", err);
+              },
+            },
+            TokenState::Invalid => {
+              let _ = watch_tx.send(UserTokenState::Invalid);
+            },
+          }
+        }
+      }
+    });
+
+    Some(WatchStream::new(watch_rx))
+  }
+
   fn set_enable_sync(&self, uid: i64, enable: bool) {
     info!("{} cloud sync: {}", uid, enable);
     self.enable_sync.store(enable, Ordering::SeqCst);

+ 1 - 1
frontend/rust-lib/flowy-server/src/local_server/impls/database.rs

@@ -1,5 +1,5 @@
 use anyhow::Error;
-use collab_define::CollabType;
+use collab_entity::CollabType;
 
 use flowy_database_deps::cloud::{
   CollabObjectUpdate, CollabObjectUpdateByOid, DatabaseCloudService, DatabaseSnapshot,

+ 1 - 1
frontend/rust-lib/flowy-server/src/local_server/impls/user.rs

@@ -1,7 +1,7 @@
 use std::sync::Arc;
 
 use anyhow::Error;
-use collab_define::CollabObject;
+use collab_entity::CollabObject;
 use lazy_static::lazy_static;
 use parking_lot::Mutex;
 

+ 11 - 1
frontend/rust-lib/flowy-server/src/server.rs

@@ -1,15 +1,18 @@
 use std::sync::Arc;
 
+use anyhow::Error;
 use client_api::ws::{WSConnectStateReceiver, WebSocketChannel};
-use collab_define::CollabObject;
+use collab_entity::CollabObject;
 use collab_plugins::cloud_storage::RemoteCollabStorage;
 use parking_lot::RwLock;
+use tokio_stream::wrappers::WatchStream;
 
 use flowy_database_deps::cloud::DatabaseCloudService;
 use flowy_document_deps::cloud::DocumentCloudService;
 use flowy_folder_deps::cloud::FolderCloudService;
 use flowy_storage::FileStorageService;
 use flowy_user_deps::cloud::UserCloudService;
+use flowy_user_deps::entities::UserTokenState;
 use lib_infra::future::FutureResult;
 
 pub trait AppFlowyEncryption: Send + Sync + 'static {
@@ -34,6 +37,13 @@ where
 /// and functionalities in AppFlowy. The methods provided ensure efficient, asynchronous operations
 /// for managing and accessing user data, folders, collaborative objects, and documents in a cloud environment.
 pub trait AppFlowyServer: Send + Sync + 'static {
+  fn set_token(&self, _token: &str) -> Result<(), Error> {
+    Ok(())
+  }
+
+  fn subscribe_token_state(&self) -> Option<WatchStream<UserTokenState>> {
+    None
+  }
   /// Enables or disables server sync.
   ///
   /// # Arguments

+ 3 - 2
frontend/rust-lib/flowy-server/src/supabase/api/collab_storage.rs

@@ -3,10 +3,11 @@ use std::sync::{Arc, Weak};
 
 use anyhow::Error;
 use chrono::{DateTime, Utc};
+use client_api::collab_sync::collab_msg::MsgId;
 use collab::preclude::merge_updates_v1;
-use collab_define::CollabObject;
+use collab_entity::CollabObject;
 use collab_plugins::cloud_storage::{
-  MsgId, RemoteCollabSnapshot, RemoteCollabState, RemoteCollabStorage, RemoteUpdateReceiver,
+  RemoteCollabSnapshot, RemoteCollabState, RemoteCollabStorage, RemoteUpdateReceiver,
 };
 use parking_lot::Mutex;
 use tokio::task::spawn_blocking;

+ 1 - 1
frontend/rust-lib/flowy-server/src/supabase/api/database.rs

@@ -1,5 +1,5 @@
 use anyhow::Error;
-use collab_define::CollabType;
+use collab_entity::CollabType;
 use tokio::sync::oneshot::channel;
 
 use flowy_database_deps::cloud::{

+ 1 - 1
frontend/rust-lib/flowy-server/src/supabase/api/document.rs

@@ -1,8 +1,8 @@
 use anyhow::Error;
 use collab::core::origin::CollabOrigin;
-use collab_define::CollabType;
 use collab_document::blocks::DocumentData;
 use collab_document::document::Document;
+use collab_entity::CollabType;
 use tokio::sync::oneshot::channel;
 
 use flowy_document_deps::cloud::{DocumentCloudService, DocumentSnapshot};

+ 1 - 1
frontend/rust-lib/flowy-server/src/supabase/api/folder.rs

@@ -3,7 +3,7 @@ use std::str::FromStr;
 use anyhow::Error;
 use chrono::{DateTime, Utc};
 use collab::core::origin::CollabOrigin;
-use collab_define::CollabType;
+use collab_entity::CollabType;
 use serde_json::Value;
 use tokio::sync::oneshot::channel;
 

+ 1 - 1
frontend/rust-lib/flowy-server/src/supabase/api/request.rs

@@ -7,7 +7,7 @@ use std::time::Duration;
 
 use anyhow::Error;
 use chrono::{DateTime, Utc};
-use collab_define::{CollabObject, CollabType};
+use collab_entity::{CollabObject, CollabType};
 use collab_plugins::cloud_storage::RemoteCollabSnapshot;
 use serde_json::Value;
 use tokio_retry::strategy::FixedInterval;

+ 1 - 1
frontend/rust-lib/flowy-server/src/supabase/api/user.rs

@@ -9,7 +9,7 @@ use std::time::Duration;
 use anyhow::Error;
 use collab::core::collab::MutexCollab;
 use collab::core::origin::CollabOrigin;
-use collab_define::{CollabObject, CollabType};
+use collab_entity::{CollabObject, CollabType};
 use parking_lot::RwLock;
 use serde_json::Value;
 use tokio::sync::oneshot::channel;

+ 1 - 1
frontend/rust-lib/flowy-server/src/supabase/define.rs

@@ -1,4 +1,4 @@
-use collab_define::CollabType;
+use collab_entity::CollabType;
 
 pub const AF_COLLAB_UPDATE_TABLE: &str = "af_collab_update";
 pub const AF_COLLAB_KEY_COLUMN: &str = "key";

+ 1 - 1
frontend/rust-lib/flowy-server/src/supabase/server.rs

@@ -1,7 +1,7 @@
 use std::collections::HashMap;
 use std::sync::{Arc, Weak};
 
-use collab_define::CollabObject;
+use collab_entity::CollabObject;
 use collab_plugins::cloud_storage::{RemoteCollabStorage, RemoteUpdateSender};
 use parking_lot::RwLock;
 

+ 1 - 1
frontend/rust-lib/flowy-server/tests/supabase_test/database_test.rs

@@ -1,4 +1,4 @@
-use collab_define::{CollabObject, CollabType};
+use collab_entity::{CollabObject, CollabType};
 use uuid::Uuid;
 
 use flowy_user_deps::entities::AuthResponse;

+ 1 - 1
frontend/rust-lib/flowy-server/tests/supabase_test/folder_test.rs

@@ -1,5 +1,5 @@
 use assert_json_diff::assert_json_eq;
-use collab_define::{CollabObject, CollabType};
+use collab_entity::{CollabObject, CollabType};
 use serde_json::json;
 use uuid::Uuid;
 use yrs::types::ToJson;

+ 5 - 13
frontend/rust-lib/flowy-server/tests/supabase_test/user_test.rs

@@ -54,20 +54,12 @@ async fn supabase_update_user_profile_test() {
     .await
     .unwrap();
 
+  let params = UpdateUserProfileParams::new(user.user_id)
+    .with_name("123")
+    .with_email(format!("{}@test.com", Uuid::new_v4()));
+
   user_service
-    .update_user(
-      UserCredentials::from_uid(user.user_id),
-      UpdateUserProfileParams {
-        uid: user.user_id,
-        name: Some("123".to_string()),
-        email: Some(format!("{}@test.com", Uuid::new_v4())),
-        password: None,
-        icon_url: None,
-        openai_key: None,
-        stability_ai_key: None,
-        encryption_sign: None,
-      },
-    )
+    .update_user(UserCredentials::from_uid(user.user_id), params)
     .await
     .unwrap();
 

+ 1 - 1
frontend/rust-lib/flowy-test/Cargo.toml

@@ -40,7 +40,7 @@ collab-document = { version = "0.1.0" }
 collab-folder = { version = "0.1.0" }
 collab-database = { version = "0.1.0" }
 collab-plugins = { version = "0.1.0" }
-collab-define = { version = "0.1.0" }
+collab-entity = { version = "0.1.0" }
 
 [dev-dependencies]
 dotenv = "0.15.0"

+ 1 - 1
frontend/rust-lib/flowy-test/tests/database/supabase_test/helper.rs

@@ -5,7 +5,7 @@ use collab::core::collab::MutexCollab;
 use collab::core::origin::CollabOrigin;
 use collab::preclude::updates::decoder::Decode;
 use collab::preclude::{merge_updates_v1, JsonValue, Update};
-use collab_define::CollabType;
+use collab_entity::CollabType;
 
 use flowy_database2::entities::{DatabasePB, DatabaseViewIdPB, RepeatedDatabaseSnapshotPB};
 use flowy_database2::event_map::DatabaseEvent::*;

+ 1 - 1
frontend/rust-lib/flowy-test/tests/user/supabase_test/auth_test.rs

@@ -2,8 +2,8 @@ use std::collections::HashMap;
 
 use assert_json_diff::assert_json_eq;
 use collab_database::rows::database_row_document_id_from_row_id;
-use collab_define::CollabType;
 use collab_document::blocks::DocumentData;
+use collab_entity::CollabType;
 use collab_folder::core::FolderData;
 use nanoid::nanoid;
 use serde_json::json;

+ 1 - 1
frontend/rust-lib/flowy-user-deps/Cargo.toml

@@ -10,7 +10,7 @@ lib-infra = { path = "../../../shared-lib/lib-infra" }
 flowy-error  = { workspace = true }
 uuid = { version = "1.3.3", features = ["v4"] }
 serde = { version = "1.0", features = ["derive"] }
-collab-define = { version = "0.1.0" }
+collab-entity = { version = "0.1.0" }
 serde_json = { version = "1.0"}
 serde_repr = "0.1"
 chrono = { version = "0.4.31", default-features = false, features = ["clock", "serde"] }

+ 1 - 1
frontend/rust-lib/flowy-user-deps/src/cloud.rs

@@ -3,7 +3,7 @@ use std::fmt::{Display, Formatter};
 use std::str::FromStr;
 
 use anyhow::Error;
-use collab_define::CollabObject;
+use collab_entity::CollabObject;
 use serde::{Deserialize, Serialize};
 use serde_json::Value;
 use uuid::Uuid;

+ 20 - 8
frontend/rust-lib/flowy-user-deps/src/entities.rs

@@ -268,6 +268,7 @@ pub struct UpdateUserProfileParams {
   pub openai_key: Option<String>,
   pub stability_ai_key: Option<String>,
   pub encryption_sign: Option<String>,
+  pub token: Option<String>,
 }
 
 impl UpdateUserProfileParams {
@@ -278,23 +279,28 @@ impl UpdateUserProfileParams {
     }
   }
 
-  pub fn with_name(mut self, name: &str) -> Self {
-    self.name = Some(name.to_owned());
+  pub fn with_token(mut self, token: String) -> Self {
+    self.token = Some(token);
+    self
+  }
+
+  pub fn with_name<T: ToString>(mut self, name: T) -> Self {
+    self.name = Some(name.to_string());
     self
   }
 
-  pub fn with_email(mut self, email: &str) -> Self {
-    self.email = Some(email.to_owned());
+  pub fn with_email<T: ToString>(mut self, email: T) -> Self {
+    self.email = Some(email.to_string());
     self
   }
 
-  pub fn with_password(mut self, password: &str) -> Self {
-    self.password = Some(password.to_owned());
+  pub fn with_password<T: ToString>(mut self, password: T) -> Self {
+    self.password = Some(password.to_string());
     self
   }
 
-  pub fn with_icon_url(mut self, icon_url: &str) -> Self {
-    self.icon_url = Some(icon_url.to_owned());
+  pub fn with_icon_url<T: ToString>(mut self, icon_url: T) -> Self {
+    self.icon_url = Some(icon_url.to_string());
     self
   }
 
@@ -372,3 +378,9 @@ pub struct AFCloudOAuthParams {
   pub sign_in_url: String,
   pub device_id: String,
 }
+
+#[derive(Clone, Debug)]
+pub enum UserTokenState {
+  Refresh { token: String },
+  Invalid,
+}

+ 2 - 1
frontend/rust-lib/flowy-user/Cargo.toml

@@ -21,7 +21,7 @@ collab-folder = { version = "0.1.0" }
 collab-document = { version = "0.1.0" }
 collab-database = { version = "0.1.0" }
 collab-user = { version = "0.1.0" }
-collab-define = { version = "0.1.0" }
+collab-entity = { version = "0.1.0" }
 flowy-user-deps = { workspace = true }
 anyhow = "1.0.75"
 
@@ -46,6 +46,7 @@ fancy-regex = "0.11.0"
 uuid = { version = "1.3.3", features = [ "v4"] }
 chrono = { version = "0.4.31", default-features = false, features = ["clock"] }
 base64 = "^0.21"
+tokio-stream = "0.1.14"
 
 [dev-dependencies]
 nanoid = "0.4.0"

+ 1 - 1
frontend/rust-lib/flowy-user/src/entities/reminder.rs

@@ -1,4 +1,4 @@
-use collab_define::reminder::{ObjectType, Reminder, ReminderMeta};
+use collab_entity::reminder::{ObjectType, Reminder, ReminderMeta};
 use flowy_derive::ProtoBuf;
 use std::collections::HashMap;
 

+ 1 - 0
frontend/rust-lib/flowy-user/src/entities/user_profile.rs

@@ -197,6 +197,7 @@ impl TryInto<UpdateUserProfileParams> for UpdateUserProfilePayloadPB {
       icon_url,
       openai_key,
       encryption_sign: None,
+      token: None,
       stability_ai_key,
     })
   }

+ 10 - 0
frontend/rust-lib/flowy-user/src/event_map.rs

@@ -1,5 +1,6 @@
 use std::sync::{Arc, Weak};
 
+use collab_database::database::WatchStream;
 use collab_folder::core::FolderData;
 use strum_macros::Display;
 
@@ -111,6 +112,11 @@ pub trait UserStatusCallback: Send + Sync + 'static {
 /// The user cloud service provider.
 /// The provider can be supabase, firebase, aws, or any other cloud service.
 pub trait UserCloudServiceProvider: Send + Sync + 'static {
+  fn set_token(&self, token: &str) -> Result<(), FlowyError>;
+  fn subscribe_token_state(&self) -> Option<WatchStream<UserTokenState>> {
+    None
+  }
+
   fn set_enable_sync(&self, uid: i64, enable_sync: bool);
   fn set_encrypt_secret(&self, secret: String);
   fn set_auth_type(&self, auth_type: AuthType);
@@ -123,6 +129,10 @@ impl<T> UserCloudServiceProvider for Arc<T>
 where
   T: UserCloudServiceProvider,
 {
+  fn set_token(&self, token: &str) -> Result<(), FlowyError> {
+    (**self).set_token(token)
+  }
+
   fn set_enable_sync(&self, uid: i64, enable_sync: bool) {
     (**self).set_enable_sync(uid, enable_sync)
   }

+ 44 - 14
frontend/rust-lib/flowy-user/src/manager.rs

@@ -4,8 +4,8 @@ use std::sync::{Arc, Weak};
 use collab_user::core::MutexUserAwareness;
 use serde_json::Value;
 use tokio::sync::{Mutex, RwLock};
-use tracing::{debug, info};
-use uuid::Uuid;
+use tokio_stream::StreamExt;
+use tracing::{debug, error, info, instrument};
 
 use collab_integrate::collab_builder::AppFlowyCollabBuilder;
 use collab_integrate::RocksCollabDB;
@@ -112,18 +112,46 @@ impl UserManager {
     Arc::downgrade(&self.store_preferences)
   }
 
-  /// Initializes the user session, including data migrations and user awareness configuration.
+  /// Initializes the user session, including data migrations and user awareness configuration. This function
+  /// will be invoked each time the user opens the application.
   ///
-  /// This asynchronous function starts by retrieving the current session. If the session is successfully obtained,
-  /// it will attempt a local data migration for the user. After ensuring the user's data is migrated and up-to-date,
+  /// Starts by retrieving the current session. If the session is successfully obtained, it will attempt
+  /// a local data migration for the user. After ensuring the user's data is migrated and up-to-date,
   /// the function will set up the collaboration configuration and initialize the user's awareness. Upon successful
   /// completion, a user status callback is invoked to signify that the initialization process is complete.
   pub async fn init<C: UserStatusCallback + 'static, I: CollabInteract>(
     &self,
     user_status_callback: C,
     collab_interact: I,
-  ) {
+  ) -> Result<(), FlowyError> {
     if let Ok(session) = self.get_session() {
+      let user = self.get_user_profile(session.user_id).await?;
+      if let Err(err) = self.cloud_services.set_token(&user.token) {
+        error!("Set token failed: {}", err);
+      }
+
+      // Subscribe the token state
+      let weak_pool = Arc::downgrade(&self.db_pool(user.uid)?);
+      if let Some(mut token_state_rx) = self.cloud_services.subscribe_token_state() {
+        tokio::spawn(async move {
+          while let Some(token_state) = token_state_rx.next().await {
+            match token_state {
+              UserTokenState::Refresh { token } => {
+                if token != user.token {
+                  if let Some(pool) = weak_pool.upgrade() {
+                    // Save the new token
+                    if let Err(err) = save_user_token(user.uid, pool, token) {
+                      error!("Save user token failed: {}", err);
+                    }
+                  }
+                }
+              },
+              UserTokenState::Invalid => {},
+            }
+          }
+        });
+      }
+
       // Do the user data migration if needed
       match (
         self.database.get_collab_db(session.user_id),
@@ -164,6 +192,7 @@ impl UserManager {
     }
     *self.user_status_callback.write().await = Arc::new(user_status_callback);
     *self.collab_interact.write().await = Arc::new(collab_interact);
+    Ok(())
   }
 
   pub fn db_connection(&self, uid: i64) -> Result<DBConnection, FlowyError> {
@@ -396,14 +425,8 @@ impl UserManager {
 
   pub async fn check_user(&self) -> Result<(), FlowyError> {
     let user_id = self.get_session()?.user_id;
-    let credential = UserCredentials::from_uid(user_id);
-    let auth_service = self.cloud_services.get_user_service()?;
-    auth_service.check_user(credential).await?;
-    Ok(())
-  }
-
-  pub async fn check_user_with_uuid(&self, uuid: &Uuid) -> Result<(), FlowyError> {
-    let credential = UserCredentials::from_uuid(uuid.to_string());
+    let user = self.get_user_profile(user_id).await?;
+    let credential = UserCredentials::new(Some(user.token), Some(user_id), None);
     let auth_service = self.cloud_services.get_user_service()?;
     auth_service.check_user(credential).await?;
     Ok(())
@@ -681,3 +704,10 @@ fn save_user_profile_change(
     .send();
   Ok(())
 }
+
+#[instrument(level = "info", skip_all, err)]
+fn save_user_token(uid: i64, pool: Arc<ConnectionPool>, token: String) -> FlowyResult<()> {
+  let params = UpdateUserProfileParams::new(uid).with_token(token);
+  let changeset = UserTableChangeset::new(params);
+  save_user_profile_change(uid, pool, changeset)
+}

+ 1 - 1
frontend/rust-lib/flowy-user/src/migrations/sync_new_user.rs

@@ -9,7 +9,7 @@ use collab::preclude::Collab;
 use collab_database::database::get_database_row_ids;
 use collab_database::rows::database_row_document_id_from_row_id;
 use collab_database::user::{get_database_with_views, DatabaseWithViews};
-use collab_define::{CollabObject, CollabType};
+use collab_entity::{CollabObject, CollabType};
 use collab_folder::core::{Folder, View, ViewLayout};
 use parking_lot::Mutex;
 

+ 1 - 1
frontend/rust-lib/flowy-user/src/services/collab_interact.rs

@@ -1,5 +1,5 @@
 use anyhow::Error;
-use collab_define::reminder::Reminder;
+use collab_entity::reminder::Reminder;
 
 use lib_infra::future::FutureResult;
 

+ 2 - 2
frontend/rust-lib/flowy-user/src/services/user_awareness.rs

@@ -2,8 +2,8 @@ use std::sync::{Arc, Weak};
 
 use anyhow::Context;
 use collab::core::collab::{CollabRawData, MutexCollab};
-use collab_define::reminder::Reminder;
-use collab_define::CollabType;
+use collab_entity::reminder::Reminder;
+use collab_entity::CollabType;
 use collab_user::core::{MutexUserAwareness, UserAwareness};
 use tracing::{error, trace};
 

+ 3 - 0
frontend/rust-lib/flowy-user/src/services/user_sql.rs

@@ -74,6 +74,7 @@ pub struct UserTableChangeset {
   pub icon_url: Option<String>,
   pub openai_key: Option<String>,
   pub encryption_type: Option<String>,
+  pub token: Option<String>,
   pub stability_ai_key: Option<String>,
 }
 
@@ -91,6 +92,7 @@ impl UserTableChangeset {
       icon_url: params.icon_url,
       openai_key: params.openai_key,
       encryption_type,
+      token: params.token,
       stability_ai_key: params.stability_ai_key,
     }
   }
@@ -105,6 +107,7 @@ impl UserTableChangeset {
       icon_url: Some(user_profile.icon_url),
       openai_key: Some(user_profile.openai_key),
       encryption_type: Some(encryption_type),
+      token: Some(user_profile.token),
       stability_ai_key: Some(user_profile.stability_ai_key),
     }
   }

+ 1 - 1
frontend/rust-lib/flowy-user/src/services/user_workspace.rs

@@ -1,7 +1,7 @@
 use std::convert::TryFrom;
 use std::sync::Arc;
 
-use collab_define::{CollabObject, CollabType};
+use collab_entity::{CollabObject, CollabType};
 
 use flowy_error::{FlowyError, FlowyResult};
 use flowy_sqlite::schema::user_workspace_table;

+ 1 - 1
frontend/scripts/tool/update_collab_source.sh

@@ -15,7 +15,7 @@ switch_deps() {
     if grep -q 'git = "https://github.com/AppFlowy-IO/AppFlowy-Collab"' "$cargo_toml"; then
         cp "$cargo_toml" "$cargo_toml.bak"
         # Switch to local paths
-        for crate in collab collab-folder collab-document collab-database collab-plugins collab-user collab-define collab-sync-protocol collab-persistence; do
+        for crate in collab collab-folder collab-document collab-database collab-plugins collab-user collab-entity collab-sync-protocol collab-persistence; do
             sed -i '' \
                 -e "s#${crate} = { git = \"https://github.com/AppFlowy-IO/AppFlowy-Collab\", rev = \"[a-f0-9]*\" }#${crate} = { path = \"$repo_path/$crate\" }#g" \
                 "$cargo_toml"