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