mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
parent
71f80be8f7
commit
cceee80799
@ -27,8 +27,8 @@ class NetworkListener {
|
||||
return _updateConnectionStatus(result);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
_connectivitySubscription.cancel();
|
||||
Future<void> stop() async {
|
||||
await _connectivitySubscription.cancel();
|
||||
}
|
||||
|
||||
Future<void> _updateConnectionStatus(ConnectivityResult result) async {
|
||||
|
@ -2,6 +2,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||
import 'package:appflowy_backend/appflowy_backend.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
@ -104,6 +105,9 @@ Future<void> initGetIt(
|
||||
config,
|
||||
),
|
||||
),
|
||||
dispose: (launcher) async {
|
||||
await launcher.dispose();
|
||||
},
|
||||
);
|
||||
getIt.registerSingleton<PluginSandbox>(PluginSandbox());
|
||||
|
||||
@ -130,6 +134,7 @@ abstract class LaunchTask {
|
||||
LaunchTaskType get type => LaunchTaskType.dataProcessing;
|
||||
|
||||
Future<void> initialize(LaunchContext context);
|
||||
Future<void> dispose();
|
||||
}
|
||||
|
||||
class AppLauncher {
|
||||
@ -153,6 +158,14 @@ class AppLauncher {
|
||||
await task.initialize(context);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
Log.info('AppLauncher dispose');
|
||||
for (final task in tasks) {
|
||||
await task.dispose();
|
||||
}
|
||||
tasks.clear();
|
||||
}
|
||||
}
|
||||
|
||||
enum IntegrationMode {
|
||||
|
@ -86,6 +86,9 @@ class InitAppWidgetTask extends LaunchTask {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {}
|
||||
}
|
||||
|
||||
class ApplicationWidget extends StatefulWidget {
|
||||
|
@ -1,11 +1,10 @@
|
||||
import 'package:appflowy/env/env.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/user/application/auth/auth_service.dart';
|
||||
import 'package:appflowy/user/application/user_auth_listener.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
|
||||
class InitAppFlowyCloudTask extends LaunchTask {
|
||||
final _authStateListener = UserAuthStateListener();
|
||||
UserAuthStateListener? _authStateListener;
|
||||
bool isLoggingOut = false;
|
||||
|
||||
@override
|
||||
@ -13,19 +12,24 @@ class InitAppFlowyCloudTask extends LaunchTask {
|
||||
if (!isAppFlowyCloudEnabled) {
|
||||
return;
|
||||
}
|
||||
_authStateListener = UserAuthStateListener();
|
||||
|
||||
_authStateListener.start(
|
||||
_authStateListener?.start(
|
||||
didSignIn: () {
|
||||
isLoggingOut = false;
|
||||
},
|
||||
onInvalidAuth: (message) async {
|
||||
Log.error(message);
|
||||
await getIt<AuthService>().signOut();
|
||||
// TODO(nathan): Show a dialog to notify the user that the session is expired.
|
||||
if (!isLoggingOut) {
|
||||
await runAppFlowy();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
await _authStateListener?.stop();
|
||||
_authStateListener = null;
|
||||
}
|
||||
}
|
||||
|
@ -14,4 +14,7 @@ class HotKeyTask extends LaunchTask {
|
||||
}
|
||||
await hotKeyManager.unregisterAll();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {}
|
||||
}
|
||||
|
@ -25,4 +25,7 @@ class PluginLoadTask extends LaunchTask {
|
||||
config: CalendarPluginConfig(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {}
|
||||
}
|
||||
|
@ -10,4 +10,7 @@ class InitLocalizationTask extends LaunchTask {
|
||||
await EasyLocalization.ensureInitialized();
|
||||
EasyLocalization.logger.enableBuildModes = [];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {}
|
||||
}
|
||||
|
@ -18,4 +18,7 @@ class PlatformErrorCatcherTask extends LaunchTask {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {}
|
||||
}
|
||||
|
@ -11,4 +11,9 @@ class InitPlatformServiceTask extends LaunchTask {
|
||||
Future<void> initialize(LaunchContext context) async {
|
||||
getIt<NetworkListener>().start();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
await getIt<NetworkListener>().stop();
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,9 @@ class InitRustSDKTask extends LaunchTask {
|
||||
context.getIt<FlowySDK>().setEnv(env);
|
||||
await context.getIt<FlowySDK>().init(dir);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {}
|
||||
}
|
||||
|
||||
AppFlowyEnv getAppFlowyEnv() {
|
||||
|
@ -54,6 +54,12 @@ class InitSupabaseTask extends LaunchTask {
|
||||
registerProtocolHandler(appflowyDeepLinkSchema);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
await realtimeService?.dispose();
|
||||
supabase?.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// customize the supabase auth storage
|
||||
|
@ -71,4 +71,7 @@ class InitAppWindowTask extends LaunchTask with WindowListener {
|
||||
final position = await windowManager.getPosition();
|
||||
WindowSizeManager().setPosition(position);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {}
|
||||
}
|
||||
|
@ -63,15 +63,22 @@ class BackendAuthService implements AuthService {
|
||||
@override
|
||||
Future<Either<FlowyError, UserProfilePB>> signUpAsGuest({
|
||||
Map<String, String> params = const {},
|
||||
}) {
|
||||
}) async {
|
||||
const password = "Guest!@123456";
|
||||
final uid = uuid();
|
||||
final userEmail = "$uid@appflowy.io";
|
||||
return signUp(
|
||||
name: LocaleKeys.defaultUsername.tr(),
|
||||
password: password,
|
||||
email: userEmail,
|
||||
);
|
||||
|
||||
final request = SignUpPayloadPB.create()
|
||||
..name = LocaleKeys.defaultUsername.tr()
|
||||
..email = userEmail
|
||||
..password = password
|
||||
// When sign up as guest, the auth type is always local.
|
||||
..authType = AuthTypePB.Local
|
||||
..deviceId = await getDeviceId();
|
||||
final response = await UserEventSignUp(request).send().then(
|
||||
(value) => value.swap(),
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -36,6 +36,7 @@ class SupbaseRealtimeService {
|
||||
isLoggingOut = false;
|
||||
},
|
||||
onInvalidAuth: (message) async {
|
||||
Log.error(message);
|
||||
await getIt<AuthService>().signOut();
|
||||
channel?.unsubscribe();
|
||||
channel = null;
|
||||
|
@ -54,7 +54,7 @@ class SettingsUserView extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
_buildUserIconSetting(context),
|
||||
if (isCloudEnabled) ...[
|
||||
if (isCloudEnabled && user.authType != AuthTypePB.Local) ...[
|
||||
const VSpace(12),
|
||||
UserEmailInput(user.email)
|
||||
],
|
||||
|
30
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
30
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -762,7 +762,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -1292,7 +1292,7 @@ dependencies = [
|
||||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
"itoa 1.0.6",
|
||||
"phf 0.11.2",
|
||||
"phf 0.8.0",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
@ -1438,7 +1438,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -2781,7 +2781,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@ -2797,7 +2797,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"jsonwebtoken",
|
||||
@ -3232,7 +3232,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@ -4307,7 +4307,6 @@ 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",
|
||||
]
|
||||
|
||||
@ -4399,19 +4398,6 @@ 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"
|
||||
@ -4915,7 +4901,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "realtime-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab",
|
||||
@ -5637,7 +5623,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared_entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab-entity",
|
||||
|
@ -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 = "141354bfa9d08c387cf9beb9697b89b052790e89" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "cc6b451104e7154b38df5ae9c4e7215a61fcf172" }
|
||||
# Please use the following script to update collab.
|
||||
# Working directory: frontend
|
||||
#
|
||||
|
32
frontend/rust-lib/Cargo.lock
generated
32
frontend/rust-lib/Cargo.lock
generated
@ -660,7 +660,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -1138,7 +1138,7 @@ dependencies = [
|
||||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
"itoa",
|
||||
"phf 0.11.2",
|
||||
"phf 0.8.0",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
@ -1265,7 +1265,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -2440,7 +2440,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@ -2456,7 +2456,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"jsonwebtoken",
|
||||
@ -2816,7 +2816,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@ -3623,7 +3623,7 @@ version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
|
||||
dependencies = [
|
||||
"phf_macros 0.8.0",
|
||||
"phf_macros",
|
||||
"phf_shared 0.8.0",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
@ -3643,7 +3643,6 @@ 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",
|
||||
]
|
||||
|
||||
@ -3711,19 +3710,6 @@ 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.31",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.8.0"
|
||||
@ -4265,7 +4251,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "realtime-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"collab",
|
||||
@ -4886,7 +4872,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared_entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=141354bfa9d08c387cf9beb9697b89b052790e89#141354bfa9d08c387cf9beb9697b89b052790e89"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=cc6b451104e7154b38df5ae9c4e7215a61fcf172#cc6b451104e7154b38df5ae9c4e7215a61fcf172"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab-entity",
|
||||
|
@ -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 = "141354bfa9d08c387cf9beb9697b89b052790e89" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "cc6b451104e7154b38df5ae9c4e7215a61fcf172" }
|
||||
# Please use the following script to update collab.
|
||||
# Working directory: frontend
|
||||
#
|
||||
|
@ -107,7 +107,7 @@ impl EventIntegrationTest {
|
||||
*self.auth_type.write() = auth_type;
|
||||
}
|
||||
|
||||
pub async fn init_user(&self) -> UserProfilePB {
|
||||
pub async fn init_anon_user(&self) -> UserProfilePB {
|
||||
self.sign_up_as_guest().await.user_profile
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ pub struct FolderTest {
|
||||
impl FolderTest {
|
||||
pub async fn new() -> Self {
|
||||
let sdk = EventIntegrationTest::new();
|
||||
let _ = sdk.init_user().await;
|
||||
let _ = sdk.init_anon_user().await;
|
||||
let workspace = create_workspace(&sdk, "FolderWorkspace", "Folder test workspace").await;
|
||||
let parent_view = create_app(&sdk, &workspace.id, "Folder App", "Folder test app").await;
|
||||
let view = create_view(
|
||||
|
@ -14,7 +14,7 @@ async fn af_cloud_sign_up_test() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn af_cloud_update_user_metadata_of_open_ai_key() {
|
||||
async fn af_cloud_update_user_metadata() {
|
||||
if get_af_cloud_config().is_some() {
|
||||
let test = EventIntegrationTest::new();
|
||||
let user = test.af_cloud_sign_up().await;
|
||||
@ -25,12 +25,17 @@ async fn af_cloud_update_user_metadata_of_open_ai_key() {
|
||||
test
|
||||
.update_user_profile(UpdateUserProfilePayloadPB {
|
||||
id: user.id,
|
||||
openai_key: Some("new openai_key".to_string()),
|
||||
openai_key: Some("new openai key".to_string()),
|
||||
stability_ai_key: Some("new stability ai key".to_string()),
|
||||
..Default::default()
|
||||
})
|
||||
.await;
|
||||
|
||||
let new_profile = test.get_user_profile().await.unwrap();
|
||||
assert_eq!(new_profile.openai_key, "new openai_key".to_string());
|
||||
assert_eq!(new_profile.openai_key, "new openai key".to_string());
|
||||
assert_eq!(
|
||||
new_profile.stability_ai_key,
|
||||
"new stability ai key".to_string()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use nanoid::nanoid;
|
||||
|
||||
use event_integration::{event_builder::EventBuilder, EventIntegrationTest};
|
||||
use flowy_user::entities::{UpdateUserProfilePayloadPB, UserProfilePB};
|
||||
use flowy_user::entities::{AuthTypePB, UpdateUserProfilePayloadPB, UserProfilePB};
|
||||
use flowy_user::{errors::ErrorCode, event_map::UserEvent::*};
|
||||
|
||||
use crate::user::local_test::helper::*;
|
||||
@ -20,20 +20,24 @@ async fn user_profile_get_failed() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn user_profile_get() {
|
||||
async fn anon_user_profile_get() {
|
||||
let test = EventIntegrationTest::new();
|
||||
let user_profile = test.init_user().await;
|
||||
let user_profile = test.init_anon_user().await;
|
||||
let user = EventBuilder::new(test.clone())
|
||||
.event(GetUserProfile)
|
||||
.sync_send()
|
||||
.parse::<UserProfilePB>();
|
||||
assert_eq!(user_profile, user);
|
||||
assert_eq!(user_profile.id, user.id);
|
||||
assert_eq!(user_profile.openai_key, user.openai_key);
|
||||
assert_eq!(user_profile.stability_ai_key, user.stability_ai_key);
|
||||
assert_eq!(user_profile.workspace_id, user.workspace_id);
|
||||
assert_eq!(user_profile.auth_type, AuthTypePB::Local);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn user_update_with_name() {
|
||||
let sdk = EventIntegrationTest::new();
|
||||
let user = sdk.init_user().await;
|
||||
let user = sdk.init_anon_user().await;
|
||||
let new_name = "hello_world".to_owned();
|
||||
let request = UpdateUserProfilePayloadPB::new(user.id).name(&new_name);
|
||||
let _ = EventBuilder::new(sdk.clone())
|
||||
@ -52,7 +56,7 @@ async fn user_update_with_name() {
|
||||
#[tokio::test]
|
||||
async fn user_update_with_ai_key() {
|
||||
let sdk = EventIntegrationTest::new();
|
||||
let user = sdk.init_user().await;
|
||||
let user = sdk.init_anon_user().await;
|
||||
let openai_key = "openai_key".to_owned();
|
||||
let stability_ai_key = "stability_ai_key".to_owned();
|
||||
let request = UpdateUserProfilePayloadPB::new(user.id)
|
||||
@ -73,9 +77,9 @@ async fn user_update_with_ai_key() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn user_update_with_email() {
|
||||
async fn anon_user_update_with_email() {
|
||||
let sdk = EventIntegrationTest::new();
|
||||
let user = sdk.init_user().await;
|
||||
let user = sdk.init_anon_user().await;
|
||||
let new_email = format!("{}@gmail.com", nanoid!(6));
|
||||
let request = UpdateUserProfilePayloadPB::new(user.id).email(&new_email);
|
||||
let _ = EventBuilder::new(sdk.clone())
|
||||
@ -87,13 +91,14 @@ async fn user_update_with_email() {
|
||||
.sync_send()
|
||||
.parse::<UserProfilePB>();
|
||||
|
||||
assert_eq!(user_profile.email, new_email,);
|
||||
// When the user is anonymous, the email is empty no matter what you set
|
||||
assert!(user_profile.email.is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn user_update_with_invalid_email() {
|
||||
let test = EventIntegrationTest::new();
|
||||
let user = test.init_user().await;
|
||||
let user = test.init_anon_user().await;
|
||||
for email in invalid_email_test_case() {
|
||||
let request = UpdateUserProfilePayloadPB::new(user.id).email(&email);
|
||||
assert_eq!(
|
||||
@ -112,7 +117,7 @@ async fn user_update_with_invalid_email() {
|
||||
#[tokio::test]
|
||||
async fn user_update_with_invalid_password() {
|
||||
let test = EventIntegrationTest::new();
|
||||
let user = test.init_user().await;
|
||||
let user = test.init_anon_user().await;
|
||||
for password in invalid_password_test_case() {
|
||||
let request = UpdateUserProfilePayloadPB::new(user.id).password(&password);
|
||||
|
||||
@ -129,7 +134,7 @@ async fn user_update_with_invalid_password() {
|
||||
#[tokio::test]
|
||||
async fn user_update_with_invalid_name() {
|
||||
let test = EventIntegrationTest::new();
|
||||
let user = test.init_user().await;
|
||||
let user = test.init_anon_user().await;
|
||||
let request = UpdateUserProfilePayloadPB::new(user.id).name("");
|
||||
assert!(EventBuilder::new(test.clone())
|
||||
.event(UpdateUserProfile)
|
||||
|
@ -194,17 +194,6 @@ async fn sign_up_as_guest_and_then_update_to_existing_cloud_user_test() {
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn check_not_exist_user_test() {
|
||||
if let Some(test) = FlowySupabaseTest::new() {
|
||||
let err = test
|
||||
.check_user_with_uuid(&uuid::Uuid::new_v4().to_string())
|
||||
.await
|
||||
.unwrap_err();
|
||||
assert_eq!(err.code, ErrorCode::RecordNotFound);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_user_profile_test() {
|
||||
if let Some(test) = FlowySupabaseTest::new() {
|
||||
|
@ -23,7 +23,7 @@ use flowy_server::supabase::api::*;
|
||||
use flowy_server::{AppFlowyEncryption, EncryptionImpl};
|
||||
use flowy_server_config::af_cloud_config::AFCloudConfiguration;
|
||||
use flowy_server_config::supabase_config::SupabaseConfiguration;
|
||||
use flowy_user::entities::{AuthTypePB, UpdateUserProfilePayloadPB, UserCredentialsPB};
|
||||
use flowy_user::entities::{AuthTypePB, UpdateUserProfilePayloadPB};
|
||||
use flowy_user::errors::FlowyError;
|
||||
use flowy_user::event_map::UserCloudServiceProvider;
|
||||
use flowy_user::event_map::UserEvent::*;
|
||||
@ -49,19 +49,6 @@ impl FlowySupabaseTest {
|
||||
Some(Self { inner: test })
|
||||
}
|
||||
|
||||
pub async fn check_user_with_uuid(&self, uuid: &str) -> Result<(), FlowyError> {
|
||||
match EventBuilder::new(self.inner.clone())
|
||||
.event(CheckUser)
|
||||
.payload(UserCredentialsPB::from_uuid(uuid))
|
||||
.async_send()
|
||||
.await
|
||||
.error()
|
||||
{
|
||||
None => Ok(()),
|
||||
Some(error) => Err(error),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_user_profile(
|
||||
&self,
|
||||
payload: UpdateUserProfilePayloadPB,
|
||||
|
@ -91,6 +91,11 @@ impl ServerProvider {
|
||||
}
|
||||
|
||||
pub fn set_server_type(&self, server_type: ServerType) {
|
||||
let old_server_type = self.server_type.read().clone();
|
||||
if server_type != old_server_type {
|
||||
self.providers.write().remove(&old_server_type);
|
||||
}
|
||||
|
||||
*self.server_type.write() = server_type;
|
||||
}
|
||||
|
||||
@ -179,9 +184,9 @@ struct LocalServerDBImpl {
|
||||
}
|
||||
|
||||
impl LocalServerDB for LocalServerDBImpl {
|
||||
fn get_user_profile(&self, uid: i64) -> Result<Option<UserProfile>, FlowyError> {
|
||||
fn get_user_profile(&self, uid: i64) -> Result<UserProfile, FlowyError> {
|
||||
let sqlite_db = open_user_db(&self.storage_path, uid)?;
|
||||
let user_profile = get_user_profile(&sqlite_db, uid).ok();
|
||||
let user_profile = get_user_profile(&sqlite_db, uid)?;
|
||||
Ok(user_profile)
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ pub struct DatabaseEditorTest {
|
||||
impl DatabaseEditorTest {
|
||||
pub async fn new_grid() -> Self {
|
||||
let sdk = EventIntegrationTest::new();
|
||||
let _ = sdk.init_user().await;
|
||||
let _ = sdk.init_anon_user().await;
|
||||
|
||||
let params = make_test_grid();
|
||||
let view_test = ViewTest::new_grid_view(&sdk, params.to_json_bytes().unwrap()).await;
|
||||
@ -47,7 +47,7 @@ impl DatabaseEditorTest {
|
||||
|
||||
pub async fn new_no_date_grid() -> Self {
|
||||
let sdk = EventIntegrationTest::new();
|
||||
let _ = sdk.init_user().await;
|
||||
let _ = sdk.init_anon_user().await;
|
||||
|
||||
let params = make_no_date_test_grid();
|
||||
let view_test = ViewTest::new_grid_view(&sdk, params.to_json_bytes().unwrap()).await;
|
||||
@ -56,7 +56,7 @@ impl DatabaseEditorTest {
|
||||
|
||||
pub async fn new_board() -> Self {
|
||||
let sdk = EventIntegrationTest::new();
|
||||
let _ = sdk.init_user().await;
|
||||
let _ = sdk.init_anon_user().await;
|
||||
|
||||
let params = make_test_board();
|
||||
let view_test = ViewTest::new_grid_view(&sdk, params.to_json_bytes().unwrap()).await;
|
||||
@ -65,7 +65,7 @@ impl DatabaseEditorTest {
|
||||
|
||||
pub async fn new_calendar() -> Self {
|
||||
let sdk = EventIntegrationTest::new();
|
||||
let _ = sdk.init_user().await;
|
||||
let _ = sdk.init_anon_user().await;
|
||||
|
||||
let params = make_test_calendar();
|
||||
let view_test = ViewTest::new_grid_view(&sdk, params.to_json_bytes().unwrap()).await;
|
||||
|
@ -58,10 +58,9 @@ async fn get_checklist_cell_options(test: &DatabaseFilterTest) -> Vec<String> {
|
||||
.get_cell(&field.id, &test.row_details[0].row.id)
|
||||
.await;
|
||||
row_cell
|
||||
.map_or_else(
|
||||
|| ChecklistCellData::default(),
|
||||
|cell| ChecklistCellData::from(&cell),
|
||||
)
|
||||
.map_or(ChecklistCellData::default(), |cell| {
|
||||
ChecklistCellData::from(&cell)
|
||||
})
|
||||
.options
|
||||
.into_iter()
|
||||
.map(|option| option.id)
|
||||
|
@ -102,15 +102,14 @@ where
|
||||
fn get_user_profile(
|
||||
&self,
|
||||
_credential: UserCredentials,
|
||||
) -> FutureResult<Option<UserProfile>, FlowyError> {
|
||||
) -> FutureResult<UserProfile, FlowyError> {
|
||||
let try_get_client = self.server.try_get_client();
|
||||
FutureResult::new(async move {
|
||||
let client = try_get_client?;
|
||||
let profile = client.get_profile().await?;
|
||||
let token = client.get_token()?;
|
||||
let profile = user_profile_from_af_profile(token, profile)?;
|
||||
|
||||
Ok(Some(profile))
|
||||
Ok(profile)
|
||||
})
|
||||
}
|
||||
|
||||
@ -122,29 +121,6 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn check_user(&self, credential: UserCredentials) -> FutureResult<(), Error> {
|
||||
let try_get_client = self.server.try_get_client();
|
||||
FutureResult::new(async move {
|
||||
// from params
|
||||
let token = credential.token.ok_or(anyhow!("expecting token"))?;
|
||||
let uid = credential.uid.ok_or(anyhow!("expecting uid"))?;
|
||||
|
||||
// from cloud
|
||||
let client = try_get_client?;
|
||||
let profile = client.get_profile().await?;
|
||||
let client_token = client.access_token()?;
|
||||
|
||||
// compare and check
|
||||
if uid != profile.uid {
|
||||
return Err(anyhow!("uid mismatch"));
|
||||
}
|
||||
if token != client_token {
|
||||
return Err(anyhow!("token mismatch"));
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn add_workspace_member(
|
||||
&self,
|
||||
user_email: String,
|
||||
|
@ -86,7 +86,7 @@ impl AppFlowyServer for AFCloudServer {
|
||||
fn set_token(&self, token: &str) -> Result<(), Error> {
|
||||
self
|
||||
.client
|
||||
.set_token(token)
|
||||
.restore_token(token)
|
||||
.map_err(|err| Error::new(FlowyError::unauthorized().with_context(err)))
|
||||
}
|
||||
|
||||
|
@ -102,21 +102,24 @@ impl UserCloudService for LocalServerUserAuthServiceImpl {
|
||||
FutureResult::new(async { Ok(()) })
|
||||
}
|
||||
|
||||
fn get_user_profile(
|
||||
&self,
|
||||
_credential: UserCredentials,
|
||||
) -> FutureResult<Option<UserProfile>, FlowyError> {
|
||||
FutureResult::new(async { Ok(None) })
|
||||
fn get_user_profile(&self, credential: UserCredentials) -> FutureResult<UserProfile, FlowyError> {
|
||||
let result = match credential.uid {
|
||||
None => Err(FlowyError::record_not_found()),
|
||||
Some(uid) => {
|
||||
self.db.get_user_profile(uid).map(|mut profile| {
|
||||
// We don't want to expose the email in the local server
|
||||
profile.email = "".to_string();
|
||||
profile
|
||||
})
|
||||
},
|
||||
};
|
||||
FutureResult::new(async { result })
|
||||
}
|
||||
|
||||
fn get_all_user_workspaces(&self, _uid: i64) -> FutureResult<Vec<UserWorkspace>, Error> {
|
||||
FutureResult::new(async { Ok(vec![]) })
|
||||
}
|
||||
|
||||
fn check_user(&self, _credential: UserCredentials) -> FutureResult<(), Error> {
|
||||
FutureResult::new(async { Ok(()) })
|
||||
}
|
||||
|
||||
fn add_workspace_member(
|
||||
&self,
|
||||
_user_email: String,
|
||||
|
@ -21,7 +21,7 @@ use crate::local_server::impls::{
|
||||
use crate::AppFlowyServer;
|
||||
|
||||
pub trait LocalServerDB: Send + Sync + 'static {
|
||||
fn get_user_profile(&self, uid: i64) -> Result<Option<UserProfile>, FlowyError>;
|
||||
fn get_user_profile(&self, uid: i64) -> Result<UserProfile, FlowyError>;
|
||||
fn get_user_workspace(&self, uid: i64) -> Result<Option<UserWorkspace>, FlowyError>;
|
||||
fn get_collab_updates(&self, uid: i64, object_id: &str) -> Result<Vec<Vec<u8>>, FlowyError>;
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ use std::collections::HashMap;
|
||||
use std::future::Future;
|
||||
use std::iter::Take;
|
||||
use std::pin::Pin;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::time::Duration;
|
||||
|
||||
@ -199,10 +198,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn get_user_profile(
|
||||
&self,
|
||||
credential: UserCredentials,
|
||||
) -> FutureResult<Option<UserProfile>, FlowyError> {
|
||||
fn get_user_profile(&self, credential: UserCredentials) -> FutureResult<UserProfile, FlowyError> {
|
||||
let try_get_postgrest = self.server.try_get_postgrest();
|
||||
let uid = credential
|
||||
.uid
|
||||
@ -212,8 +208,8 @@ where
|
||||
let postgrest = try_get_postgrest?;
|
||||
let user_profile_resp = get_user_profile(postgrest, GetUserProfileParams::Uid(uid)).await?;
|
||||
match user_profile_resp {
|
||||
None => Ok(None),
|
||||
Some(response) => Ok(Some(UserProfile {
|
||||
None => Err(FlowyError::record_not_found()),
|
||||
Some(response) => Ok(UserProfile {
|
||||
uid: response.uid,
|
||||
email: response.email,
|
||||
name: response.name,
|
||||
@ -225,7 +221,7 @@ where
|
||||
auth_type: AuthType::Supabase,
|
||||
encryption_type: EncryptionType::from_sign(&response.encryption_sign),
|
||||
updated_at: response.updated_at.timestamp(),
|
||||
})),
|
||||
}),
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -238,18 +234,6 @@ where
|
||||
Ok(user_workspaces)
|
||||
})
|
||||
}
|
||||
|
||||
fn check_user(&self, credential: UserCredentials) -> FutureResult<(), Error> {
|
||||
let try_get_postgrest = self.server.try_get_postgrest();
|
||||
let uuid = credential.uuid.and_then(|uuid| Uuid::from_str(&uuid).ok());
|
||||
let uid = credential.uid;
|
||||
FutureResult::new(async move {
|
||||
let postgrest = try_get_postgrest?;
|
||||
check_user(postgrest, uid, uuid).await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn add_workspace_member(
|
||||
&self,
|
||||
_user_email: String,
|
||||
@ -512,6 +496,7 @@ async fn update_user_profile(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
async fn check_user(
|
||||
postgrest: Arc<PostgresWrapper>,
|
||||
uid: Option<i64>,
|
||||
|
@ -1,6 +1,7 @@
|
||||
use uuid::Uuid;
|
||||
|
||||
use flowy_encrypt::{encrypt_text, generate_encryption_secret};
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_user_deps::entities::*;
|
||||
use lib_infra::box_any::BoxAny;
|
||||
|
||||
@ -66,7 +67,6 @@ async fn supabase_update_user_profile_test() {
|
||||
let user_profile = user_service
|
||||
.get_user_profile(UserCredentials::from_uid(user.user_id))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(user_profile.name, "123");
|
||||
@ -89,7 +89,6 @@ async fn supabase_get_user_profile_test() {
|
||||
user_service
|
||||
.get_user_profile(credential.clone())
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@ -100,12 +99,12 @@ async fn supabase_get_not_exist_user_profile_test() {
|
||||
}
|
||||
|
||||
let user_service = user_auth_service();
|
||||
let result = user_service
|
||||
let result: FlowyError = user_service
|
||||
.get_user_profile(UserCredentials::from_uid(i64::MAX))
|
||||
.await
|
||||
.unwrap();
|
||||
.unwrap_err();
|
||||
// user not found
|
||||
assert!(result.is_none());
|
||||
assert!(result.is_record_not_found());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@ -134,7 +133,6 @@ async fn user_encryption_sign_test() {
|
||||
let user_profile: UserProfile = user_service
|
||||
.get_user_profile(UserCredentials::from_uid(user.user_id))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
user_profile.encryption_type,
|
||||
|
@ -89,16 +89,11 @@ pub trait UserCloudService: Send + Sync + 'static {
|
||||
|
||||
/// Get the user information using the user's token or uid
|
||||
/// return None if the user is not found
|
||||
fn get_user_profile(
|
||||
&self,
|
||||
credential: UserCredentials,
|
||||
) -> FutureResult<Option<UserProfile>, FlowyError>;
|
||||
fn get_user_profile(&self, credential: UserCredentials) -> FutureResult<UserProfile, FlowyError>;
|
||||
|
||||
/// Return the all the workspaces of the user
|
||||
fn get_all_user_workspaces(&self, uid: i64) -> FutureResult<Vec<UserWorkspace>, Error>;
|
||||
|
||||
fn check_user(&self, credential: UserCredentials) -> FutureResult<(), Error>;
|
||||
|
||||
fn add_workspace_member(
|
||||
&self,
|
||||
user_email: String,
|
||||
|
@ -82,30 +82,29 @@ pub async fn init_user_handler(
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(manager))]
|
||||
pub async fn check_user_handler(
|
||||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> Result<(), FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
manager.check_user().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(manager), err)]
|
||||
pub async fn get_user_profile_handler(
|
||||
manager: AFPluginState<Weak<UserManager>>,
|
||||
) -> DataResult<UserProfilePB, FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let uid = manager.get_session()?.user_id;
|
||||
let user_profile = manager.get_user_profile(uid).await?;
|
||||
let mut user_profile = manager.get_user_profile(uid).await?;
|
||||
|
||||
let weak_manager = Arc::downgrade(&manager);
|
||||
let cloned_user_profile = user_profile.clone();
|
||||
|
||||
// Refresh the user profile in the background
|
||||
tokio::spawn(async move {
|
||||
if let Some(manager) = weak_manager.upgrade() {
|
||||
let _ = manager.refresh_user_profile(&cloned_user_profile).await;
|
||||
}
|
||||
});
|
||||
|
||||
// When the user is logged in with a local account, the email field is a placeholder and should
|
||||
// not be exposed to the client. So we set the email field to an empty string.
|
||||
if user_profile.auth_type == AuthType::Local {
|
||||
user_profile.email = "".to_string();
|
||||
}
|
||||
|
||||
event!(
|
||||
tracing::Level::DEBUG,
|
||||
"Get user profile: {:?}",
|
||||
|
@ -30,7 +30,6 @@ pub fn init(user_session: Weak<UserManager>) -> AFPlugin {
|
||||
.event(UserEvent::GetUserProfile, get_user_profile_handler)
|
||||
.event(UserEvent::SignOut, sign_out)
|
||||
.event(UserEvent::UpdateUserProfile, update_user_profile_handler)
|
||||
.event(UserEvent::CheckUser, check_user_handler)
|
||||
.event(UserEvent::SetAppearanceSetting, set_appearance_setting)
|
||||
.event(UserEvent::GetAppearanceSetting, get_appearance_setting)
|
||||
.event(UserEvent::GetUserSetting, get_user_setting)
|
||||
@ -232,11 +231,8 @@ pub enum UserEvent {
|
||||
#[event(output = "UserProfilePB")]
|
||||
GetUserProfile = 4,
|
||||
|
||||
/// Check the user current session is valid or not
|
||||
#[event(output = "UserProfilePB")]
|
||||
CheckUser = 5,
|
||||
|
||||
/// Initialize resources for the current user after launching the application
|
||||
///
|
||||
#[event()]
|
||||
InitUser = 6,
|
||||
|
||||
|
@ -97,7 +97,7 @@ impl UserManager {
|
||||
while let Ok(update) = rx.recv().await {
|
||||
if let Some(user_manager) = weak_user_manager.upgrade() {
|
||||
if let Err(err) = user_manager.handler_user_update(update).await {
|
||||
tracing::error!("handler_user_update failed: {:?}", err);
|
||||
error!("handler_user_update failed: {:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,10 +172,10 @@ impl UserManager {
|
||||
info!("Did apply migrations: {:?}", applied_migrations);
|
||||
}
|
||||
},
|
||||
Err(e) => tracing::error!("User data migration failed: {:?}", e),
|
||||
Err(e) => error!("User data migration failed: {:?}", e),
|
||||
}
|
||||
},
|
||||
_ => tracing::error!("Failed to get collab db or sqlite pool"),
|
||||
_ => error!("Failed to get collab db or sqlite pool"),
|
||||
}
|
||||
self.set_collab_config(&session);
|
||||
// Init the user awareness
|
||||
@ -193,7 +193,7 @@ impl UserManager {
|
||||
)
|
||||
.await
|
||||
{
|
||||
tracing::error!("Failed to call did_init callback: {:?}", e);
|
||||
error!("Failed to call did_init callback: {:?}", e);
|
||||
}
|
||||
}
|
||||
*self.user_status_callback.write().await = Arc::new(user_status_callback);
|
||||
@ -253,7 +253,7 @@ impl UserManager {
|
||||
.did_sign_in(user_profile.uid, &latest_workspace, &session.device_id)
|
||||
.await
|
||||
{
|
||||
tracing::error!("Failed to call did_sign_in callback: {:?}", e);
|
||||
error!("Failed to call did_sign_in callback: {:?}", e);
|
||||
}
|
||||
send_auth_state_notification(AuthStateChangedPB {
|
||||
state: AuthStatePB::AuthStateSignIn,
|
||||
@ -349,7 +349,6 @@ impl UserManager {
|
||||
UserAwarenessDataSource::Remote
|
||||
};
|
||||
|
||||
event!(tracing::Level::DEBUG, "Sign up response: {:?}", response);
|
||||
if response.is_new_user {
|
||||
if let Some(old_user) = migration_user {
|
||||
let new_user = MigrationUser {
|
||||
@ -403,9 +402,8 @@ impl UserManager {
|
||||
|
||||
let server = self.cloud_services.get_user_service()?;
|
||||
tokio::spawn(async move {
|
||||
match server.sign_out(None).await {
|
||||
Ok(_) => {},
|
||||
Err(e) => event!(tracing::Level::ERROR, "{:?}", e),
|
||||
if let Err(err) = server.sign_out(None).await {
|
||||
event!(tracing::Level::ERROR, "{:?}", err);
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
@ -437,15 +435,6 @@ impl UserManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn check_user(&self) -> Result<(), FlowyError> {
|
||||
let user_id = self.get_session()?.user_id;
|
||||
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(())
|
||||
}
|
||||
|
||||
/// Fetches the user profile for the given user ID.
|
||||
pub async fn get_user_profile(&self, uid: i64) -> Result<UserProfile, FlowyError> {
|
||||
let user: UserProfile = user_table::dsl::user_table
|
||||
@ -457,27 +446,63 @@ impl UserManager {
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "info", skip_all)]
|
||||
pub async fn refresh_user_profile(
|
||||
&self,
|
||||
old_user_profile: &UserProfile,
|
||||
) -> FlowyResult<UserProfile> {
|
||||
pub async fn refresh_user_profile(&self, old_user_profile: &UserProfile) -> FlowyResult<()> {
|
||||
let uid = old_user_profile.uid;
|
||||
let new_user_profile: UserProfile = self
|
||||
let result: Result<UserProfile, FlowyError> = self
|
||||
.cloud_services
|
||||
.get_user_service()?
|
||||
.get_user_profile(UserCredentials::from_uid(uid))
|
||||
.await?
|
||||
.ok_or_else(|| FlowyError::new(ErrorCode::RecordNotFound, "User not found"))?;
|
||||
.await;
|
||||
|
||||
if new_user_profile.updated_at > old_user_profile.updated_at {
|
||||
check_encryption_sign(old_user_profile, &new_user_profile.encryption_type.sign());
|
||||
match result {
|
||||
Ok(new_user_profile) => {
|
||||
// If the authentication type has changed, it indicates that the user has signed in
|
||||
// using a different release package but is sharing the same data folder.
|
||||
// In such cases, notify the frontend to log out.
|
||||
if old_user_profile.auth_type != AuthType::Local
|
||||
&& new_user_profile.auth_type != old_user_profile.auth_type
|
||||
{
|
||||
event!(
|
||||
tracing::Level::INFO,
|
||||
"User login with different cloud: {:?} -> {:?}",
|
||||
old_user_profile.auth_type,
|
||||
new_user_profile.auth_type
|
||||
);
|
||||
|
||||
// Save the new user profile
|
||||
let changeset = UserTableChangeset::from_user_profile(new_user_profile.clone());
|
||||
let _ = upsert_user_profile_change(uid, self.database.get_pool(uid)?, changeset);
|
||||
send_auth_state_notification(AuthStateChangedPB {
|
||||
state: AuthStatePB::InvalidAuth,
|
||||
message: "User login with different cloud".to_string(),
|
||||
})
|
||||
.send();
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// If the user profile is updated, save the new user profile
|
||||
if new_user_profile.updated_at > old_user_profile.updated_at {
|
||||
check_encryption_sign(old_user_profile, &new_user_profile.encryption_type.sign());
|
||||
// Save the new user profile
|
||||
let changeset = UserTableChangeset::from_user_profile(new_user_profile);
|
||||
let _ = upsert_user_profile_change(uid, self.database.get_pool(uid)?, changeset);
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
Err(err) => {
|
||||
// If the user is not found, notify the frontend to logout
|
||||
if err.is_record_not_found() {
|
||||
event!(
|
||||
tracing::Level::INFO,
|
||||
"User is not found on the server when refreshing profile"
|
||||
);
|
||||
|
||||
send_auth_state_notification(AuthStateChangedPB {
|
||||
state: AuthStatePB::InvalidAuth,
|
||||
message: "User is not found on the server".to_string(),
|
||||
})
|
||||
.send();
|
||||
}
|
||||
Err(err)
|
||||
},
|
||||
}
|
||||
|
||||
Ok(new_user_profile)
|
||||
}
|
||||
|
||||
pub fn user_dir(&self, uid: i64) -> String {
|
||||
@ -680,7 +705,7 @@ impl UserManager {
|
||||
)
|
||||
.await
|
||||
{
|
||||
tracing::error!("Sync user data to cloud failed: {:?}", err);
|
||||
error!("Sync user data to cloud failed: {:?}", err);
|
||||
}
|
||||
|
||||
// Save the old user workspace setting.
|
||||
|
@ -26,6 +26,7 @@ pub(crate) fn send_notification(id: &str, ty: UserNotification) -> NotificationB
|
||||
NotificationBuilder::new(id, ty, USER_OBSERVABLE_SOURCE)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "trace")]
|
||||
pub(crate) fn send_auth_state_notification(payload: AuthStateChangedPB) -> NotificationBuilder {
|
||||
NotificationBuilder::new(
|
||||
"auth_state_change_notification",
|
||||
|
Loading…
Reference in New Issue
Block a user