mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2026-01-06 12:21:48 +00:00
Merge pull request #7788 from AppFlowy-IO/local_auth_type
refactor: local auth type
This commit is contained in:
commit
f72739d98d
@ -181,37 +181,37 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0
|
||||
appflowy_backend: 144c20d8bfb298c4e10fa3fa6701a9f41bf98b88
|
||||
connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d
|
||||
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
|
||||
app_links: 3da4c36b46cac3bf24eb897f1a6ce80bda109874
|
||||
appflowy_backend: 78f6a053f756e6bc29bcc5a2106cbe77b756e97a
|
||||
connectivity_plus: 481668c94744c30c53b8895afb39159d1e619bdf
|
||||
device_info_plus: 71ffc6ab7634ade6267c7a93088ed7e4f74e5896
|
||||
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
|
||||
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
|
||||
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
|
||||
flowy_infra_ui: 0455e1fa8c51885aa1437848e361e99419f34ebc
|
||||
file_picker: 9b3292d7c8bc68c8a7bf8eb78f730e49c8efc517
|
||||
flowy_infra_ui: 931b73a18b54a392ab6152eebe29a63a30751f53
|
||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||
fluttertoast: e9a18c7be5413da53898f660530c56f35edfba9c
|
||||
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
||||
integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573
|
||||
irondash_engine_context: 3458bf979b90d616ffb8ae03a150bafe2e860cc9
|
||||
keyboard_height_plugin: 43fa8bba20fd5c4fdeed5076466b8b9d43cc6b86
|
||||
open_filex: 6e26e659846ec990262224a12ef1c528bb4edbe4
|
||||
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
|
||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
|
||||
fluttertoast: 76fea30fcf04176325f6864c87306927bd7d2038
|
||||
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
|
||||
integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e
|
||||
irondash_engine_context: 8e58ca8e0212ee9d1c7dc6a42121849986c88486
|
||||
keyboard_height_plugin: ef70a8181b29f27670e9e2450814ca6b6dc05b05
|
||||
open_filex: 432f3cd11432da3e39f47fcc0df2b1603854eff1
|
||||
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
|
||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||
saver_gallery: 76172dc4bf6b40e66d694948ada9ff402304dd87
|
||||
saver_gallery: af2d0c762dafda254e0ad025ef0dabd6506cd490
|
||||
SDWebImage: b9a731e1d6307f44ca703b3976d18c24ca561e84
|
||||
Sentry: 1fe34e9c2cbba1e347623610d26db121dcb569f1
|
||||
sentry_flutter: a39c2a2d67d5e5b9cb0b94a4985c76dd5b3fc737
|
||||
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
|
||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
|
||||
super_native_extensions: 4916b3c627a9c7fffdc48a23a9eca0b1ac228fa7
|
||||
sentry_flutter: e24b397f9a61fa5bbefd8279c3b2242ca86faa90
|
||||
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
||||
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
|
||||
super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4
|
||||
SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780
|
||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
||||
webview_flutter_wkwebview: 0982481e3d9c78fd5c6f62a002fcd24fc791f1e4
|
||||
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
||||
webview_flutter_wkwebview: 44d4dee7d7056d5ad185d25b38404436d56c547c
|
||||
|
||||
PODFILE CHECKSUM: d0d9b4ff572d8695c38eb3f9b490f55cdfc57eca
|
||||
|
||||
|
||||
@ -202,8 +202,7 @@ class MobileViewBottomSheetBody extends StatelessWidget {
|
||||
List<Widget> _buildPublishActions(BuildContext context) {
|
||||
final userProfile = context.read<MobileViewPageBloc>().state.userProfilePB;
|
||||
// the publish feature is only available for AppFlowy Cloud
|
||||
if (userProfile == null ||
|
||||
userProfile.authType != AuthenticatorPB.AppFlowyCloud) {
|
||||
if (userProfile == null || userProfile.authType != AuthTypePB.Server) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
@ -194,7 +194,7 @@ class _MobileWorkspace extends StatelessWidget {
|
||||
context.read<UserWorkspaceBloc>().add(
|
||||
UserWorkspaceEvent.openWorkspace(
|
||||
workspace.workspaceId,
|
||||
workspace.authType,
|
||||
workspace.workspaceAuthType,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@ -48,7 +48,7 @@ class HomePageSettingsPopupMenu extends StatelessWidget {
|
||||
text: LocaleKeys.settings_popupMenuItem_settings.tr(),
|
||||
),
|
||||
// only show the member items in cloud mode
|
||||
if (userProfile.authType == AuthenticatorPB.AppFlowyCloud) ...[
|
||||
if (userProfile.authType == AuthTypePB.Server) ...[
|
||||
const PopupMenuDivider(height: 0.5),
|
||||
_buildItem(
|
||||
value: _MobileSettingsPopupMenuItem.members,
|
||||
|
||||
@ -167,7 +167,7 @@ class _MobileSpaceTabState extends State<MobileSpaceTab>
|
||||
children: [
|
||||
MobileHomeSpace(userProfile: widget.userProfile),
|
||||
// only show ai chat button for cloud user
|
||||
if (widget.userProfile.authType == AuthenticatorPB.AppFlowyCloud)
|
||||
if (widget.userProfile.authType == AuthTypePB.Server)
|
||||
Positioned(
|
||||
bottom: MediaQuery.of(context).padding.bottom + 16,
|
||||
left: 20,
|
||||
|
||||
@ -123,7 +123,7 @@ class _CreateWorkspaceButton extends StatelessWidget {
|
||||
context.read<UserWorkspaceBloc>().add(
|
||||
UserWorkspaceEvent.createWorkspace(
|
||||
name,
|
||||
AuthTypePB.CloudAuthType,
|
||||
AuthTypePB.Server,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@ -40,7 +40,7 @@ class UserSessionSettingGroup extends StatelessWidget {
|
||||
|
||||
// delete account button
|
||||
// only show the delete account button in cloud mode
|
||||
if (userProfile.authType == AuthenticatorPB.AppFlowyCloud) ...[
|
||||
if (userProfile.authType == AuthTypePB.Server) ...[
|
||||
const VSpace(16.0),
|
||||
MobileLogoutButton(
|
||||
text: LocaleKeys.button_deleteAccount.tr(),
|
||||
|
||||
@ -48,7 +48,7 @@ class AIChatPage extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// if (userProfile.authenticator != AuthenticatorPB.AppFlowyCloud) {
|
||||
// if (userProfile.authenticator != AuthTypePB.Server) {
|
||||
// return Center(
|
||||
// child: FlowyText(
|
||||
// LocaleKeys.chat_unsupportedCloudPrompt.tr(),
|
||||
|
||||
@ -31,7 +31,7 @@ class DatabaseSyncBloc extends Bloc<DatabaseSyncEvent, DatabaseSyncBlocState> {
|
||||
emit(
|
||||
state.copyWith(
|
||||
shouldShowIndicator:
|
||||
userProfile?.authType == AuthenticatorPB.AppFlowyCloud &&
|
||||
userProfile?.authType == AuthTypePB.Server &&
|
||||
databaseId != null,
|
||||
),
|
||||
);
|
||||
|
||||
@ -21,8 +21,8 @@ import 'package:appflowy/shared/af_image.dart';
|
||||
import 'package:appflowy/shared/flowy_gradient_colors.dart';
|
||||
import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/auth.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/workspace.pb.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart' hide UploadImageMenu;
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
@ -69,8 +69,7 @@ class RowBanner extends StatefulWidget {
|
||||
class _RowBannerState extends State<RowBanner> {
|
||||
final _isHovering = ValueNotifier(false);
|
||||
late final isLocalMode =
|
||||
(widget.userProfile?.authType ?? AuthenticatorPB.Local) ==
|
||||
AuthenticatorPB.Local;
|
||||
(widget.userProfile?.authType ?? AuthTypePB.Local) == AuthTypePB.Local;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
|
||||
@ -101,8 +101,8 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
||||
|
||||
bool get isLocalMode {
|
||||
final userProfilePB = state.userProfilePB;
|
||||
final type = userProfilePB?.authType ?? AuthenticatorPB.Local;
|
||||
return type == AuthenticatorPB.Local;
|
||||
final type = userProfilePB?.authType ?? AuthTypePB.Local;
|
||||
return type == AuthTypePB.Local;
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -31,8 +31,7 @@ class DocumentCollaboratorsBloc
|
||||
final userProfile = result.fold((s) => s, (f) => null);
|
||||
emit(
|
||||
state.copyWith(
|
||||
shouldShowIndicator:
|
||||
userProfile?.authType == AuthenticatorPB.AppFlowyCloud,
|
||||
shouldShowIndicator: userProfile?.authType == AuthTypePB.Server,
|
||||
),
|
||||
);
|
||||
final deviceId = ApplicationInfo.deviceId;
|
||||
|
||||
@ -30,8 +30,7 @@ class DocumentSyncBloc extends Bloc<DocumentSyncEvent, DocumentSyncBlocState> {
|
||||
);
|
||||
emit(
|
||||
state.copyWith(
|
||||
shouldShowIndicator:
|
||||
userProfile?.authType == AuthenticatorPB.AppFlowyCloud,
|
||||
shouldShowIndicator: userProfile?.authType == AuthTypePB.Server,
|
||||
),
|
||||
);
|
||||
_syncStateListener.start(
|
||||
|
||||
@ -14,8 +14,8 @@ import 'package:appflowy_backend/dispatch/error.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/file_entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/media_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/auth.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/workspace.pb.dart';
|
||||
import 'package:cross_file/cross_file.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/file_picker/file_picker_impl.dart';
|
||||
@ -185,7 +185,7 @@ Future<void> insertLocalFile(
|
||||
|
||||
// Check upload type
|
||||
final isLocalMode =
|
||||
(userProfile?.authType ?? AuthenticatorPB.Local) == AuthenticatorPB.Local;
|
||||
(userProfile?.authType ?? AuthTypePB.Local) == AuthTypePB.Local;
|
||||
|
||||
String? path;
|
||||
String? errorMsg;
|
||||
@ -230,7 +230,7 @@ Future<void> insertLocalFiles(
|
||||
|
||||
// Check upload type
|
||||
final isLocalMode =
|
||||
(userProfile?.authType ?? AuthenticatorPB.Local) == AuthenticatorPB.Local;
|
||||
(userProfile?.authType ?? AuthTypePB.Local) == AuthTypePB.Local;
|
||||
|
||||
for (final file in files) {
|
||||
final fileType = file.fileType.toMediaFileTypePB();
|
||||
|
||||
@ -225,8 +225,7 @@ class PageStyleCoverImage extends StatelessWidget {
|
||||
(s) => s,
|
||||
(f) => null,
|
||||
);
|
||||
final isAppFlowyCloud =
|
||||
userProfile?.authType == AuthenticatorPB.AppFlowyCloud;
|
||||
final isAppFlowyCloud = userProfile?.authType == AuthTypePB.Server;
|
||||
final PageStyleCoverImageType type;
|
||||
if (!isAppFlowyCloud) {
|
||||
result = await saveImageToLocalStorage(path);
|
||||
|
||||
@ -193,7 +193,7 @@ class ShareBloc extends Bloc<ShareEvent, ShareState> {
|
||||
Future<void> _updatePublishStatus(Emitter<ShareState> emit) async {
|
||||
final publishInfo = await ViewBackendService.getPublishInfo(view);
|
||||
final enablePublish = await UserBackendService.getCurrentUserProfile().fold(
|
||||
(v) => v.authType == AuthenticatorPB.AppFlowyCloud,
|
||||
(v) => v.authType == AuthTypePB.Server,
|
||||
(p) => false,
|
||||
);
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/user/application/user_service.dart';
|
||||
import 'package:appflowy/util/default_extensions.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/auth.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/workspace.pb.dart';
|
||||
import 'package:desktop_drop/desktop_drop.dart';
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
@ -294,8 +294,8 @@ class _IconUploaderState extends State<IconUploader> {
|
||||
(userProfile) => userProfile,
|
||||
(l) => null,
|
||||
);
|
||||
final isLocalMode = (userProfile?.authType ?? AuthenticatorPB.Local) ==
|
||||
AuthenticatorPB.Local;
|
||||
final isLocalMode =
|
||||
(userProfile?.authType ?? AuthTypePB.Local) == AuthTypePB.Local;
|
||||
if (isLocalMode) {
|
||||
result = await pickedImages.first.saveToLocal();
|
||||
} else {
|
||||
|
||||
@ -102,7 +102,7 @@ void _resolveUserDeps(GetIt getIt, IntegrationMode mode) {
|
||||
case AuthenticatorType.local:
|
||||
getIt.registerFactory<AuthService>(
|
||||
() => BackendAuthService(
|
||||
AuthenticatorPB.Local,
|
||||
AuthTypePB.Local,
|
||||
),
|
||||
);
|
||||
break;
|
||||
|
||||
@ -112,7 +112,7 @@ class AppFlowyCloudDeepLink {
|
||||
(_) async {
|
||||
final deviceId = await getDeviceId();
|
||||
final payload = OauthSignInPB(
|
||||
authenticator: AuthenticatorPB.AppFlowyCloud,
|
||||
authenticator: AuthTypePB.Server,
|
||||
map: {
|
||||
AuthServiceMapKeys.signInURL: uri.toString(),
|
||||
AuthServiceMapKeys.deviceId: deviceId,
|
||||
|
||||
@ -18,7 +18,7 @@ class AppFlowyCloudAuthService implements AuthService {
|
||||
AppFlowyCloudAuthService();
|
||||
|
||||
final BackendAuthService _backendAuthService = BackendAuthService(
|
||||
AuthenticatorPB.AppFlowyCloud,
|
||||
AuthTypePB.Server,
|
||||
);
|
||||
|
||||
@override
|
||||
|
||||
@ -20,7 +20,7 @@ class AppFlowyCloudMockAuthService implements AuthService {
|
||||
final String userEmail;
|
||||
|
||||
final BackendAuthService _appFlowyAuthService =
|
||||
BackendAuthService(AuthenticatorPB.AppFlowyCloud);
|
||||
BackendAuthService(AuthTypePB.Server);
|
||||
|
||||
@override
|
||||
Future<FlowyResult<UserProfilePB, FlowyError>> signUp({
|
||||
@ -48,7 +48,7 @@ class AppFlowyCloudMockAuthService implements AuthService {
|
||||
Map<String, String> params = const {},
|
||||
}) async {
|
||||
final payload = SignInUrlPayloadPB.create()
|
||||
..authenticator = AuthenticatorPB.AppFlowyCloud
|
||||
..authenticator = AuthTypePB.Server
|
||||
// don't use nanoid here, the gotrue server will transform the email
|
||||
..email = userEmail;
|
||||
|
||||
@ -58,7 +58,7 @@ class AppFlowyCloudMockAuthService implements AuthService {
|
||||
return getSignInURLResult.fold(
|
||||
(urlPB) async {
|
||||
final payload = OauthSignInPB(
|
||||
authenticator: AuthenticatorPB.AppFlowyCloud,
|
||||
authenticator: AuthTypePB.Server,
|
||||
map: {
|
||||
AuthServiceMapKeys.signInURL: urlPB.signInUrl,
|
||||
AuthServiceMapKeys.deviceId: deviceId,
|
||||
|
||||
@ -6,6 +6,7 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/auth.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
|
||||
show SignInPayloadPB, SignUpPayloadPB, UserProfilePB;
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/workspace.pb.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
@ -15,7 +16,7 @@ import 'device_id.dart';
|
||||
class BackendAuthService implements AuthService {
|
||||
BackendAuthService(this.authType);
|
||||
|
||||
final AuthenticatorPB authType;
|
||||
final AuthTypePB authType;
|
||||
|
||||
@override
|
||||
Future<FlowyResult<GotrueTokenResponsePB, FlowyError>>
|
||||
@ -71,7 +72,7 @@ class BackendAuthService implements AuthService {
|
||||
..email = userEmail
|
||||
..password = password
|
||||
// When sign up as guest, the auth type is always local.
|
||||
..authType = AuthenticatorPB.Local
|
||||
..authType = AuthTypePB.Local
|
||||
..deviceId = await getDeviceId();
|
||||
final response = await UserEventSignUp(request).send().then(
|
||||
(value) => value,
|
||||
@ -82,7 +83,7 @@ class BackendAuthService implements AuthService {
|
||||
@override
|
||||
Future<FlowyResult<UserProfilePB, FlowyError>> signUpWithOAuth({
|
||||
required String platform,
|
||||
AuthenticatorPB authType = AuthenticatorPB.Local,
|
||||
AuthTypePB authType = AuthTypePB.Local,
|
||||
Map<String, String> params = const {},
|
||||
}) async {
|
||||
return FlowyResult.failure(
|
||||
|
||||
@ -4,8 +4,8 @@ import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/user/application/password/password_http_service.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/auth.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/workspace.pb.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
@ -46,7 +46,7 @@ class PasswordBloc extends Bloc<PasswordEvent, PasswordState> {
|
||||
bool _isInitialized = false;
|
||||
|
||||
Future<void> _init() async {
|
||||
if (userProfile.authType == AuthenticatorPB.Local) {
|
||||
if (userProfile.authType == AuthTypePB.Local) {
|
||||
Log.debug('PasswordBloc: skip init because user is local authenticator');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ class AnonUserItem extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final icon = isSelected ? const FlowySvg(FlowySvgs.check_s) : null;
|
||||
final isDisabled = isSelected || user.authType != AuthenticatorPB.Local;
|
||||
final isDisabled = isSelected || user.authType != AuthTypePB.Local;
|
||||
final desc = "${user.name}\t ${user.authType}\t";
|
||||
final child = SizedBox(
|
||||
height: 30,
|
||||
|
||||
@ -2,7 +2,6 @@ import 'package:appflowy/user/application/user_listener.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/auth.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/workspace.pb.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
@ -91,7 +90,7 @@ class SettingsDialogBloc
|
||||
AFRolePB? currentWorkspaceMemberRole,
|
||||
]) async {
|
||||
if ([
|
||||
AuthenticatorPB.Local,
|
||||
AuthTypePB.Local,
|
||||
].contains(userProfile.authType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
|
||||
final currentWorkspace = result.$1;
|
||||
final workspaces = result.$2;
|
||||
final isCollabWorkspaceOn =
|
||||
userProfile.authType == AuthenticatorPB.AppFlowyCloud &&
|
||||
userProfile.authType == AuthTypePB.Server &&
|
||||
FeatureFlag.collaborativeWorkspace.isOn;
|
||||
Log.info(
|
||||
'init workspace, current workspace: ${currentWorkspace?.workspaceId}, '
|
||||
@ -54,7 +54,7 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
|
||||
Log.info('init open workspace: ${currentWorkspace.workspaceId}');
|
||||
await _userService.openWorkspace(
|
||||
currentWorkspace.workspaceId,
|
||||
currentWorkspace.authType,
|
||||
currentWorkspace.workspaceAuthType,
|
||||
);
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
|
||||
add(
|
||||
OpenWorkspace(
|
||||
currentWorkspace.workspaceId,
|
||||
currentWorkspace.authType,
|
||||
currentWorkspace.workspaceAuthType,
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -132,7 +132,7 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
|
||||
add(
|
||||
OpenWorkspace(
|
||||
s.workspaceId,
|
||||
s.authType,
|
||||
s.workspaceAuthType,
|
||||
),
|
||||
);
|
||||
})
|
||||
@ -190,7 +190,7 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
|
||||
add(
|
||||
OpenWorkspace(
|
||||
workspaces.first.workspaceId,
|
||||
workspaces.first.authType,
|
||||
workspaces.first.workspaceAuthType,
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -203,7 +203,7 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
|
||||
add(
|
||||
OpenWorkspace(
|
||||
workspaces.first.workspaceId,
|
||||
workspaces.first.authType,
|
||||
workspaces.first.workspaceAuthType,
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -369,7 +369,7 @@ class UserWorkspaceBloc extends Bloc<UserWorkspaceEvent, UserWorkspaceState> {
|
||||
add(
|
||||
OpenWorkspace(
|
||||
workspaces.first.workspaceId,
|
||||
workspaces.first.authType,
|
||||
workspaces.first.workspaceAuthType,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ class WorkspaceBloc extends Bloc<WorkspaceEvent, WorkspaceState> {
|
||||
Emitter<WorkspaceState> emit,
|
||||
) async {
|
||||
final result =
|
||||
await userService.createUserWorkspace(name, AuthTypePB.CloudAuthType);
|
||||
await userService.createUserWorkspace(name, AuthTypePB.Server);
|
||||
emit(
|
||||
result.fold(
|
||||
(workspace) {
|
||||
|
||||
@ -309,7 +309,7 @@ class _WorkspaceInfo extends StatelessWidget {
|
||||
context.read<UserWorkspaceBloc>().add(
|
||||
UserWorkspaceEvent.openWorkspace(
|
||||
workspace.workspaceId,
|
||||
workspace.authType,
|
||||
workspace.workspaceAuthType,
|
||||
),
|
||||
);
|
||||
|
||||
@ -389,7 +389,7 @@ class _CreateWorkspaceButton extends StatelessWidget {
|
||||
workspaceBloc.add(
|
||||
UserWorkspaceEvent.createWorkspace(
|
||||
name,
|
||||
AuthTypePB.CloudAuthType,
|
||||
AuthTypePB.Server,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@ -211,7 +211,7 @@ class ViewMoreActionTypeWrapper extends CustomActionCell {
|
||||
) {
|
||||
final userProfile = context.read<SpaceBloc>().userProfile;
|
||||
// move to feature doesn't support in local mode
|
||||
if (userProfile.authType != AuthenticatorPB.AppFlowyCloud) {
|
||||
if (userProfile.authType != AuthTypePB.Server) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return BlocProvider.value(
|
||||
|
||||
@ -7,8 +7,8 @@ import 'package:appflowy/workspace/presentation/settings/pages/account/account.d
|
||||
import 'package:appflowy/workspace/presentation/settings/pages/account/email/email_section.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/shared/settings_category.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/auth.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/workspace.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@ -70,7 +70,7 @@ class _SettingsAccountViewState extends State<SettingsAccountView> {
|
||||
// user email
|
||||
// Only show email if the user is authenticated and not using local auth
|
||||
if (isAuthEnabled &&
|
||||
state.userProfile.authType != AuthenticatorPB.Local) ...[
|
||||
state.userProfile.authType != AuthTypePB.Local) ...[
|
||||
SettingsCategory(
|
||||
title: LocaleKeys.newSettings_myAccount_myAccount.tr(),
|
||||
children: [
|
||||
@ -82,30 +82,26 @@ class _SettingsAccountViewState extends State<SettingsAccountView> {
|
||||
),
|
||||
AccountSignInOutSection(
|
||||
userProfile: state.userProfile,
|
||||
onAction:
|
||||
state.userProfile.authType == AuthenticatorPB.Local
|
||||
? widget.didLogin
|
||||
: widget.didLogout,
|
||||
signIn:
|
||||
state.userProfile.authType == AuthenticatorPB.Local,
|
||||
onAction: state.userProfile.authType == AuthTypePB.Local
|
||||
? widget.didLogin
|
||||
: widget.didLogout,
|
||||
signIn: state.userProfile.authType == AuthTypePB.Local,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
if (isAuthEnabled &&
|
||||
state.userProfile.authType == AuthenticatorPB.Local) ...[
|
||||
state.userProfile.authType == AuthTypePB.Local) ...[
|
||||
SettingsCategory(
|
||||
title: LocaleKeys.settings_accountPage_login_title.tr(),
|
||||
children: [
|
||||
AccountSignInOutSection(
|
||||
userProfile: state.userProfile,
|
||||
onAction:
|
||||
state.userProfile.authType == AuthenticatorPB.Local
|
||||
? widget.didLogin
|
||||
: widget.didLogout,
|
||||
signIn:
|
||||
state.userProfile.authType == AuthenticatorPB.Local,
|
||||
onAction: state.userProfile.authType == AuthTypePB.Local
|
||||
? widget.didLogin
|
||||
: widget.didLogout,
|
||||
signIn: state.userProfile.authType == AuthTypePB.Local,
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -120,7 +116,7 @@ class _SettingsAccountViewState extends State<SettingsAccountView> {
|
||||
),
|
||||
|
||||
// user deletion
|
||||
if (widget.userProfile.authType == AuthenticatorPB.AppFlowyCloud)
|
||||
if (widget.userProfile.authType == AuthTypePB.Server)
|
||||
const AccountDeletionButton(),
|
||||
],
|
||||
);
|
||||
|
||||
@ -88,7 +88,7 @@ class SettingsWorkspaceView extends StatelessWidget {
|
||||
autoSeparate: false,
|
||||
children: [
|
||||
// We don't allow changing workspace name/icon for local/offline
|
||||
if (userProfile.authType != AuthenticatorPB.Local) ...[
|
||||
if (userProfile.authType != AuthTypePB.Local) ...[
|
||||
SettingsCategory(
|
||||
title: LocaleKeys.settings_workspacePage_workspaceName_title
|
||||
.tr(),
|
||||
@ -180,7 +180,7 @@ class SettingsWorkspaceView extends StatelessWidget {
|
||||
),
|
||||
const SettingsCategorySpacer(),
|
||||
|
||||
if (userProfile.authType != AuthenticatorPB.Local) ...[
|
||||
if (userProfile.authType != AuthTypePB.Local) ...[
|
||||
SingleSettingAction(
|
||||
label: LocaleKeys.settings_workspacePage_manageWorkspace_title
|
||||
.tr(),
|
||||
|
||||
@ -140,7 +140,7 @@ class SettingsDialog extends StatelessWidget {
|
||||
case SettingsPage.shortcuts:
|
||||
return const SettingsShortcutsView();
|
||||
case SettingsPage.ai:
|
||||
if (user.authType == AuthenticatorPB.AppFlowyCloud) {
|
||||
if (user.authType == AuthTypePB.Server) {
|
||||
return SettingsAIView(
|
||||
key: ValueKey(workspaceId),
|
||||
userProfile: user,
|
||||
|
||||
@ -63,7 +63,7 @@ class SettingsMenu extends StatelessWidget {
|
||||
changeSelectedPage: changeSelectedPage,
|
||||
),
|
||||
if (FeatureFlag.membersSettings.isOn &&
|
||||
userProfile.authType == AuthenticatorPB.AppFlowyCloud)
|
||||
userProfile.authType == AuthTypePB.Server)
|
||||
SettingsMenuElement(
|
||||
page: SettingsPage.member,
|
||||
selectedPage: currentPage,
|
||||
@ -109,7 +109,7 @@ class SettingsMenu extends StatelessWidget {
|
||||
),
|
||||
changeSelectedPage: changeSelectedPage,
|
||||
),
|
||||
if (userProfile.authType == AuthenticatorPB.AppFlowyCloud)
|
||||
if (userProfile.authType == AuthTypePB.Server)
|
||||
SettingsMenuElement(
|
||||
page: SettingsPage.sites,
|
||||
selectedPage: currentPage,
|
||||
|
||||
@ -96,7 +96,7 @@ class _MoreViewActionsState extends State<MoreViewActions> {
|
||||
return BlocBuilder<SpaceBloc, SpaceState>(
|
||||
builder: (context, state) {
|
||||
if (state.spaces.isEmpty &&
|
||||
userProfile.authType == AuthenticatorPB.AppFlowyCloud) {
|
||||
userProfile.authType == AuthTypePB.Server) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ use collab_entity::CollabType;
|
||||
use flowy_core::config::AppFlowyCoreConfig;
|
||||
use flowy_core::AppFlowyCore;
|
||||
use flowy_notification::register_notification_sender;
|
||||
use flowy_user::entities::AuthenticatorPB;
|
||||
use flowy_user::entities::AuthTypePB;
|
||||
use flowy_user::errors::FlowyError;
|
||||
use lib_dispatch::runtime::AFPluginRuntime;
|
||||
use nanoid::nanoid;
|
||||
@ -59,7 +59,7 @@ impl EventIntegrationTest {
|
||||
let clean_path = config.storage_path.clone();
|
||||
let inner = init_core(config).await;
|
||||
let notification_sender = TestNotificationSender::new();
|
||||
let authenticator = Arc::new(AtomicU8::new(AuthenticatorPB::Local as u8));
|
||||
let authenticator = Arc::new(AtomicU8::new(AuthTypePB::Local as u8));
|
||||
register_notification_sender(notification_sender.clone());
|
||||
|
||||
// In case of dropping the runtime that runs the core, we need to forget the dispatcher
|
||||
|
||||
@ -17,10 +17,10 @@ use flowy_server::af_cloud::define::{USER_DEVICE_ID, USER_EMAIL, USER_SIGN_IN_UR
|
||||
use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
|
||||
use flowy_server_pub::AuthenticatorType;
|
||||
use flowy_user::entities::{
|
||||
AuthTypePB, AuthenticatorPB, ChangeWorkspaceIconPB, CloudSettingPB, CreateWorkspacePB,
|
||||
ImportAppFlowyDataPB, OauthSignInPB, OpenUserWorkspacePB, RenameWorkspacePB,
|
||||
RepeatedUserWorkspacePB, SignInUrlPB, SignInUrlPayloadPB, SignUpPayloadPB, UpdateCloudConfigPB,
|
||||
UpdateUserProfilePayloadPB, UserProfilePB, UserWorkspaceIdPB, UserWorkspacePB,
|
||||
AuthTypePB, ChangeWorkspaceIconPB, CloudSettingPB, CreateWorkspacePB, ImportAppFlowyDataPB,
|
||||
OauthSignInPB, OpenUserWorkspacePB, RenameWorkspacePB, RepeatedUserWorkspacePB, SignInUrlPB,
|
||||
SignInUrlPayloadPB, SignUpPayloadPB, UpdateCloudConfigPB, UpdateUserProfilePayloadPB,
|
||||
UserProfilePB, UserWorkspaceIdPB, UserWorkspacePB,
|
||||
};
|
||||
use flowy_user::errors::{FlowyError, FlowyResult};
|
||||
use flowy_user::event_map::UserEvent;
|
||||
@ -65,7 +65,7 @@ impl EventIntegrationTest {
|
||||
email,
|
||||
name: "appflowy".to_string(),
|
||||
password: password.clone(),
|
||||
auth_type: AuthenticatorPB::Local,
|
||||
auth_type: AuthTypePB::Local,
|
||||
device_id: uuid::Uuid::new_v4().to_string(),
|
||||
}
|
||||
.into_bytes()
|
||||
@ -113,7 +113,7 @@ impl EventIntegrationTest {
|
||||
.await;
|
||||
}
|
||||
|
||||
pub fn set_auth_type(&self, auth_type: AuthenticatorPB) {
|
||||
pub fn set_auth_type(&self, auth_type: AuthTypePB) {
|
||||
self.authenticator.store(auth_type as u8, Ordering::Release);
|
||||
}
|
||||
|
||||
@ -140,7 +140,7 @@ impl EventIntegrationTest {
|
||||
pub async fn af_cloud_sign_in_with_email(&self, email: &str) -> FlowyResult<UserProfilePB> {
|
||||
let payload = SignInUrlPayloadPB {
|
||||
email: email.to_string(),
|
||||
authenticator: AuthenticatorPB::AppFlowyCloud,
|
||||
authenticator: AuthTypePB::Server,
|
||||
};
|
||||
let sign_in_url = EventBuilder::new(self.clone())
|
||||
.event(UserEvent::GenerateSignInURL)
|
||||
@ -155,7 +155,7 @@ impl EventIntegrationTest {
|
||||
map.insert(USER_DEVICE_ID.to_string(), Uuid::new_v4().to_string());
|
||||
let payload = OauthSignInPB {
|
||||
map,
|
||||
authenticator: AuthenticatorPB::AppFlowyCloud,
|
||||
authenticator: AuthTypePB::Server,
|
||||
};
|
||||
|
||||
let user_profile = EventBuilder::new(self.clone())
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use event_integration_test::user_event::use_localhost_af_cloud;
|
||||
use event_integration_test::EventIntegrationTest;
|
||||
use flowy_core::DEFAULT_NAME;
|
||||
use flowy_user::entities::AuthenticatorPB;
|
||||
use flowy_user::entities::AuthTypePB;
|
||||
|
||||
use crate::util::unzip;
|
||||
|
||||
@ -72,7 +72,7 @@ async fn migrate_anon_user_data_to_af_cloud_test() {
|
||||
let user = test.af_cloud_sign_up().await;
|
||||
let workspace = test.get_current_workspace().await;
|
||||
println!("user workspace: {:?}", workspace.id);
|
||||
assert_eq!(user.auth_type, AuthenticatorPB::AppFlowyCloud);
|
||||
assert_eq!(user.auth_type, AuthTypePB::Server);
|
||||
|
||||
let user_first_level_views = test.get_all_workspace_views().await;
|
||||
assert_eq!(user_first_level_views.len(), 3);
|
||||
|
||||
@ -90,7 +90,10 @@ async fn af_cloud_create_workspace_test() {
|
||||
{
|
||||
// after opening new workspace
|
||||
test
|
||||
.open_workspace(&created_workspace.workspace_id, created_workspace.auth_type)
|
||||
.open_workspace(
|
||||
&created_workspace.workspace_id,
|
||||
created_workspace.workspace_auth_type,
|
||||
)
|
||||
.await;
|
||||
let folder_ws = test.folder_read_current_workspace().await;
|
||||
assert_eq!(folder_ws.id, created_workspace.workspace_id);
|
||||
@ -124,7 +127,10 @@ async fn af_cloud_open_workspace_test() {
|
||||
.create_workspace("second workspace", AuthType::AppFlowyCloud)
|
||||
.await;
|
||||
test
|
||||
.open_workspace(&user_workspace.workspace_id, user_workspace.auth_type)
|
||||
.open_workspace(
|
||||
&user_workspace.workspace_id,
|
||||
user_workspace.workspace_auth_type,
|
||||
)
|
||||
.await;
|
||||
let second_workspace = test.get_current_workspace().await;
|
||||
let second_workspace = test.get_user_workspace(&second_workspace.id).await;
|
||||
@ -144,7 +150,7 @@ async fn af_cloud_open_workspace_test() {
|
||||
test
|
||||
.open_workspace(
|
||||
&first_workspace.workspace_id,
|
||||
first_workspace.auth_type.clone(),
|
||||
first_workspace.workspace_auth_type.clone(),
|
||||
)
|
||||
.await;
|
||||
sleep(Duration::from_millis(300)).await;
|
||||
@ -155,7 +161,7 @@ async fn af_cloud_open_workspace_test() {
|
||||
test
|
||||
.open_workspace(
|
||||
&second_workspace.workspace_id,
|
||||
second_workspace.auth_type.clone(),
|
||||
second_workspace.workspace_auth_type.clone(),
|
||||
)
|
||||
.await;
|
||||
sleep(Duration::from_millis(200)).await;
|
||||
@ -168,7 +174,7 @@ async fn af_cloud_open_workspace_test() {
|
||||
test
|
||||
.open_workspace(
|
||||
&first_workspace.workspace_id,
|
||||
first_workspace.auth_type.clone(),
|
||||
first_workspace.workspace_auth_type.clone(),
|
||||
)
|
||||
.await;
|
||||
let views_1 = test.get_all_workspace_views().await;
|
||||
@ -180,7 +186,7 @@ async fn af_cloud_open_workspace_test() {
|
||||
test
|
||||
.open_workspace(
|
||||
&second_workspace.workspace_id,
|
||||
second_workspace.auth_type.clone(),
|
||||
second_workspace.workspace_auth_type.clone(),
|
||||
)
|
||||
.await;
|
||||
let views_2 = test.get_all_workspace_views().await;
|
||||
@ -239,7 +245,10 @@ async fn af_cloud_different_open_same_workspace_test() {
|
||||
let index = i % 2;
|
||||
let iter_workspace_id = &all_workspaces[index].workspace_id;
|
||||
client
|
||||
.open_workspace(iter_workspace_id, all_workspaces[index].auth_type.clone())
|
||||
.open_workspace(
|
||||
iter_workspace_id,
|
||||
all_workspaces[index].workspace_auth_type.clone(),
|
||||
)
|
||||
.await;
|
||||
if iter_workspace_id == &cloned_shared_workspace_id {
|
||||
let views = client.get_all_workspace_views().await;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use event_integration_test::user_event::{login_password, unique_email};
|
||||
use event_integration_test::{event_builder::EventBuilder, EventIntegrationTest};
|
||||
use flowy_user::entities::{AuthenticatorPB, SignInPayloadPB, SignUpPayloadPB};
|
||||
use flowy_user::entities::{AuthTypePB, SignInPayloadPB, SignUpPayloadPB};
|
||||
use flowy_user::errors::ErrorCode;
|
||||
use flowy_user::event_map::UserEvent::*;
|
||||
|
||||
@ -14,7 +14,7 @@ async fn sign_up_with_invalid_email() {
|
||||
email: email.to_string(),
|
||||
name: valid_name(),
|
||||
password: login_password(),
|
||||
auth_type: AuthenticatorPB::Local,
|
||||
auth_type: AuthTypePB::Local,
|
||||
device_id: "".to_string(),
|
||||
};
|
||||
|
||||
@ -40,7 +40,7 @@ async fn sign_in_with_invalid_email() {
|
||||
email: email.to_string(),
|
||||
password: login_password(),
|
||||
name: "".to_string(),
|
||||
auth_type: AuthenticatorPB::Local,
|
||||
auth_type: AuthTypePB::Local,
|
||||
device_id: "".to_string(),
|
||||
};
|
||||
|
||||
@ -67,7 +67,7 @@ async fn sign_in_with_invalid_password() {
|
||||
email: unique_email(),
|
||||
password,
|
||||
name: "".to_string(),
|
||||
auth_type: AuthenticatorPB::Local,
|
||||
auth_type: AuthTypePB::Local,
|
||||
device_id: "".to_string(),
|
||||
};
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::user::local_test::helper::*;
|
||||
use event_integration_test::{event_builder::EventBuilder, EventIntegrationTest};
|
||||
use flowy_user::entities::{AuthenticatorPB, UpdateUserProfilePayloadPB, UserProfilePB};
|
||||
use flowy_user::entities::{AuthTypePB, UpdateUserProfilePayloadPB, UserProfilePB};
|
||||
use flowy_user::{errors::ErrorCode, event_map::UserEvent::*};
|
||||
use nanoid::nanoid;
|
||||
#[tokio::test]
|
||||
@ -24,7 +24,7 @@ async fn anon_user_profile_get() {
|
||||
.await
|
||||
.parse::<UserProfilePB>();
|
||||
assert_eq!(user_profile.id, user.id);
|
||||
assert_eq!(user_profile.auth_type, AuthenticatorPB::Local);
|
||||
assert_eq!(user_profile.auth_type, AuthTypePB::Local);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
@ -82,12 +82,12 @@ impl ServerProvider {
|
||||
|
||||
pub fn set_auth_type(&self, new_auth_type: AuthType) {
|
||||
let old_type = self.get_auth_type();
|
||||
info!(
|
||||
"ServerProvider: set auth type from {:?} to {:?}",
|
||||
old_type, new_auth_type
|
||||
);
|
||||
|
||||
if old_type != new_auth_type {
|
||||
info!(
|
||||
"ServerProvider: auth type from {:?} to {:?}",
|
||||
old_type, new_auth_type
|
||||
);
|
||||
|
||||
self.auth_type.store(Arc::new(new_auth_type));
|
||||
if let Some((auth_type, _)) = self.providers.remove(&old_type) {
|
||||
info!("ServerProvider: remove old auth type: {:?}", auth_type);
|
||||
|
||||
@ -46,7 +46,7 @@ impl UserStatusCallbackImpl {
|
||||
|
||||
#[async_trait]
|
||||
impl UserStatusCallback for UserStatusCallbackImpl {
|
||||
async fn did_init(
|
||||
async fn on_launch_if_authenticated(
|
||||
&self,
|
||||
user_id: i64,
|
||||
cloud_config: &Option<UserCloudConfig>,
|
||||
@ -55,7 +55,6 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
||||
auth_type: &AuthType,
|
||||
) -> FlowyResult<()> {
|
||||
let workspace_id = user_workspace.workspace_id()?;
|
||||
self.server_provider.set_auth_type(*auth_type);
|
||||
|
||||
if let Some(cloud_config) = cloud_config {
|
||||
self
|
||||
@ -89,7 +88,7 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn did_sign_in(
|
||||
async fn on_sign_in(
|
||||
&self,
|
||||
user_id: i64,
|
||||
user_workspace: &UserWorkspace,
|
||||
@ -102,8 +101,6 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
||||
user_workspace,
|
||||
device_id
|
||||
);
|
||||
self.server_provider.set_auth_type(*auth_type);
|
||||
|
||||
self
|
||||
.folder_manager
|
||||
.initialize_after_sign_in(user_id)
|
||||
@ -122,7 +119,7 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn did_sign_up(
|
||||
async fn on_sign_up(
|
||||
&self,
|
||||
is_new_user: bool,
|
||||
user_profile: &UserProfile,
|
||||
@ -130,8 +127,6 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
||||
device_id: &str,
|
||||
auth_type: &AuthType,
|
||||
) -> FlowyResult<()> {
|
||||
self.server_provider.set_auth_type(*auth_type);
|
||||
|
||||
event!(
|
||||
tracing::Level::TRACE,
|
||||
"Notify did sign up: is new: {} user_workspace: {:?}, device_id: {}",
|
||||
@ -201,18 +196,17 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn did_expired(&self, _token: &str, user_id: i64) -> FlowyResult<()> {
|
||||
async fn on_token_expired(&self, _token: &str, user_id: i64) -> FlowyResult<()> {
|
||||
self.folder_manager.clear(user_id).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn open_workspace(
|
||||
async fn on_workspace_opened(
|
||||
&self,
|
||||
user_id: i64,
|
||||
user_workspace: &UserWorkspace,
|
||||
auth_type: &AuthType,
|
||||
) -> FlowyResult<()> {
|
||||
self.server_provider.set_auth_type(*auth_type);
|
||||
self
|
||||
.folder_manager
|
||||
.initialize_after_open_workspace(user_id)
|
||||
@ -236,13 +230,13 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn did_update_network(&self, reachable: bool) {
|
||||
fn on_network_status_changed(&self, reachable: bool) {
|
||||
info!("Notify did update network: reachable: {}", reachable);
|
||||
self.collab_builder.update_network(reachable);
|
||||
self.storage_manager.update_network_reachable(reachable);
|
||||
}
|
||||
|
||||
fn did_update_plans(&self, plans: Vec<SubscriptionPlan>) {
|
||||
fn on_subscription_plans_updated(&self, plans: Vec<SubscriptionPlan>) {
|
||||
let mut storage_plan_changed = false;
|
||||
for plan in &plans {
|
||||
match plan {
|
||||
@ -255,7 +249,7 @@ impl UserStatusCallback for UserStatusCallbackImpl {
|
||||
}
|
||||
}
|
||||
|
||||
fn did_update_storage_limitation(&self, can_write: bool) {
|
||||
fn on_storage_permission_updated(&self, can_write: bool) {
|
||||
if can_write {
|
||||
self.storage_manager.enable_storage_write_access();
|
||||
} else {
|
||||
|
||||
@ -84,7 +84,7 @@ impl FolderCloudService for LocalServerFolderCloudServiceImpl {
|
||||
workspace_id: &Uuid,
|
||||
view_ids: Vec<Uuid>,
|
||||
) -> Result<(), FlowyError> {
|
||||
Err(FlowyError::local_version_not_support())
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_publish_info(&self, view_id: &Uuid) -> Result<PublishInfo, FlowyError> {
|
||||
|
||||
@ -35,7 +35,7 @@ impl UserCloudService for LocalServerUserServiceImpl {
|
||||
let params = params.unbox_or_error::<SignUpParams>()?;
|
||||
let uid = ID_GEN.lock().await.next_id();
|
||||
let workspace_id = Uuid::new_v4().to_string();
|
||||
let user_workspace = UserWorkspace::new_local(&workspace_id, uid);
|
||||
let user_workspace = UserWorkspace::new_local(workspace_id, "");
|
||||
let user_name = if params.name.is_empty() {
|
||||
DEFAULT_USER_NAME()
|
||||
} else {
|
||||
@ -48,7 +48,8 @@ impl UserCloudService for LocalServerUserServiceImpl {
|
||||
latest_workspace: user_workspace.clone(),
|
||||
user_workspaces: vec![user_workspace],
|
||||
is_new_user: true,
|
||||
email: Some(params.email),
|
||||
// Anon user doesn't have email
|
||||
email: None,
|
||||
token: None,
|
||||
encryption_type: EncryptionType::NoEncryption,
|
||||
updated_at: timestamp(),
|
||||
@ -59,7 +60,9 @@ impl UserCloudService for LocalServerUserServiceImpl {
|
||||
async fn sign_in(&self, params: BoxAny) -> Result<AuthResponse, FlowyError> {
|
||||
let params: SignInParams = params.unbox_or_error::<SignInParams>()?;
|
||||
let uid = ID_GEN.lock().await.next_id();
|
||||
let user_workspace = make_user_workspace("My Workspace");
|
||||
|
||||
let workspace_id = Uuid::new_v4();
|
||||
let user_workspace = UserWorkspace::new_local(workspace_id.to_string(), "My Workspace");
|
||||
Ok(AuthResponse {
|
||||
user_id: uid,
|
||||
user_uuid: Uuid::new_v4(),
|
||||
@ -130,9 +133,9 @@ impl UserCloudService for LocalServerUserServiceImpl {
|
||||
|
||||
async fn open_workspace(&self, workspace_id: &Uuid) -> Result<UserWorkspace, FlowyError> {
|
||||
let uid = self.user.user_id()?;
|
||||
let conn = self.user.get_sqlite_db(uid)?;
|
||||
let mut conn = self.user.get_sqlite_db(uid)?;
|
||||
|
||||
let workspace = select_user_workspace(&workspace_id.to_string(), conn)?;
|
||||
let workspace = select_user_workspace(&workspace_id.to_string(), &mut conn)?;
|
||||
Ok(UserWorkspace::from(workspace))
|
||||
}
|
||||
|
||||
@ -143,7 +146,11 @@ impl UserCloudService for LocalServerUserServiceImpl {
|
||||
}
|
||||
|
||||
async fn create_workspace(&self, workspace_name: &str) -> Result<UserWorkspace, FlowyError> {
|
||||
Ok(make_user_workspace(workspace_name))
|
||||
let workspace_id = Uuid::new_v4();
|
||||
Ok(UserWorkspace::new_local(
|
||||
workspace_id.to_string(),
|
||||
workspace_name,
|
||||
))
|
||||
}
|
||||
|
||||
async fn patch_workspace(
|
||||
@ -192,15 +199,3 @@ impl UserCloudService for LocalServerUserServiceImpl {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn make_user_workspace(name: &str) -> UserWorkspace {
|
||||
UserWorkspace {
|
||||
id: Uuid::new_v4().to_string(),
|
||||
name: name.to_string(),
|
||||
created_at: Default::default(),
|
||||
workspace_database_id: Uuid::new_v4().to_string(),
|
||||
icon: "".to_string(),
|
||||
member_count: 1,
|
||||
role: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
-- Your SQL goes here
|
||||
ALTER TABLE user_workspace_table
|
||||
ADD COLUMN auth_type INTEGER NOT NULL DEFAULT 1;
|
||||
ADD COLUMN workspace_type INTEGER NOT NULL DEFAULT 1;
|
||||
|
||||
-- 2. Back‑fill from user_table.auth_type
|
||||
UPDATE user_workspace_table
|
||||
SET auth_type = (SELECT ut.auth_type
|
||||
SET workspace_type = (SELECT ut.auth_type
|
||||
FROM user_table ut
|
||||
WHERE ut.id = CAST(user_workspace_table.uid AS TEXT))
|
||||
WHERE EXISTS (SELECT 1
|
||||
|
||||
@ -107,7 +107,7 @@ diesel::table! {
|
||||
icon -> Text,
|
||||
member_count -> BigInt,
|
||||
role -> Nullable<Integer>,
|
||||
auth_type -> Integer,
|
||||
workspace_type -> Integer,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -122,10 +122,10 @@ impl UserWorkspace {
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
pub fn new_local(workspace_id: &str, _uid: i64) -> Self {
|
||||
pub fn new_local(workspace_id: String, name: &str) -> Self {
|
||||
Self {
|
||||
id: workspace_id.to_string(),
|
||||
name: "".to_string(),
|
||||
id: workspace_id,
|
||||
name: name.to_string(),
|
||||
created_at: Utc::now(),
|
||||
workspace_database_id: Uuid::new_v4().to_string(),
|
||||
icon: "".to_string(),
|
||||
|
||||
@ -17,7 +17,7 @@ pub struct UserWorkspaceTable {
|
||||
pub icon: String,
|
||||
pub member_count: i64,
|
||||
pub role: Option<i32>,
|
||||
pub auth_type: i32,
|
||||
pub workspace_type: i32,
|
||||
}
|
||||
|
||||
#[derive(AsChangeset, Identifiable, Default, Debug)]
|
||||
@ -50,18 +50,18 @@ impl UserWorkspaceTable {
|
||||
icon: workspace.icon.clone(),
|
||||
member_count: workspace.member_count,
|
||||
role: workspace.role.clone().map(|v| v as i32),
|
||||
auth_type: auth_type as i32,
|
||||
workspace_type: auth_type as i32,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_user_workspace(
|
||||
workspace_id: &str,
|
||||
mut conn: DBConnection,
|
||||
conn: &mut SqliteConnection,
|
||||
) -> FlowyResult<UserWorkspaceTable> {
|
||||
let row = user_workspace_table::dsl::user_workspace_table
|
||||
.filter(user_workspace_table::id.eq(workspace_id))
|
||||
.first::<UserWorkspaceTable>(&mut *conn)?;
|
||||
.first::<UserWorkspaceTable>(conn)?;
|
||||
Ok(row)
|
||||
}
|
||||
|
||||
@ -93,20 +93,20 @@ pub fn upsert_user_workspace(
|
||||
user_workspace: UserWorkspace,
|
||||
conn: &mut SqliteConnection,
|
||||
) -> Result<(), FlowyError> {
|
||||
let new_record = UserWorkspaceTable::from_workspace(uid, &user_workspace, auth_type)?;
|
||||
let row = UserWorkspaceTable::from_workspace(uid, &user_workspace, auth_type)?;
|
||||
diesel::insert_into(user_workspace_table::table)
|
||||
.values(new_record.clone())
|
||||
.values(row.clone())
|
||||
.on_conflict(user_workspace_table::id)
|
||||
.do_update()
|
||||
.set((
|
||||
user_workspace_table::name.eq(new_record.name),
|
||||
user_workspace_table::uid.eq(new_record.uid),
|
||||
user_workspace_table::created_at.eq(new_record.created_at),
|
||||
user_workspace_table::database_storage_id.eq(new_record.database_storage_id),
|
||||
user_workspace_table::icon.eq(new_record.icon),
|
||||
user_workspace_table::member_count.eq(new_record.member_count),
|
||||
user_workspace_table::role.eq(new_record.role),
|
||||
user_workspace_table::auth_type.eq(new_record.auth_type),
|
||||
user_workspace_table::name.eq(row.name),
|
||||
user_workspace_table::uid.eq(row.uid),
|
||||
user_workspace_table::created_at.eq(row.created_at),
|
||||
user_workspace_table::database_storage_id.eq(row.database_storage_id),
|
||||
user_workspace_table::icon.eq(row.icon),
|
||||
user_workspace_table::member_count.eq(row.member_count),
|
||||
user_workspace_table::role.eq(row.role),
|
||||
user_workspace_table::workspace_type.eq(row.workspace_type),
|
||||
))
|
||||
.execute(conn)?;
|
||||
|
||||
@ -153,7 +153,7 @@ pub fn delete_user_all_workspace(
|
||||
let n = diesel::delete(
|
||||
user_workspace_table::dsl::user_workspace_table
|
||||
.filter(user_workspace_table::uid.eq(uid))
|
||||
.filter(user_workspace_table::auth_type.eq(auth_type as i32)),
|
||||
.filter(user_workspace_table::workspace_type.eq(auth_type as i32)),
|
||||
)
|
||||
.execute(conn)?;
|
||||
info!(
|
||||
@ -172,7 +172,6 @@ pub fn delete_all_then_insert_user_workspaces(
|
||||
) -> FlowyResult<()> {
|
||||
conn.immediate_transaction(|conn| {
|
||||
delete_user_all_workspace(uid, auth_type, conn)?;
|
||||
|
||||
info!(
|
||||
"Insert {} workspaces for user {} and auth type {:?}",
|
||||
user_workspaces.len(),
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryInto;
|
||||
|
||||
use crate::entities::parser::*;
|
||||
use crate::entities::AuthTypePB;
|
||||
use crate::errors::ErrorCode;
|
||||
use client_api::entity::GotrueTokenResponse;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_user_pub::entities::*;
|
||||
|
||||
use crate::entities::parser::*;
|
||||
use crate::errors::ErrorCode;
|
||||
|
||||
#[derive(ProtoBuf, Default)]
|
||||
pub struct SignInPayloadPB {
|
||||
#[pb(index = 1)]
|
||||
@ -20,7 +20,7 @@ pub struct SignInPayloadPB {
|
||||
pub name: String,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub auth_type: AuthenticatorPB,
|
||||
pub auth_type: AuthTypePB,
|
||||
|
||||
#[pb(index = 5)]
|
||||
pub device_id: String,
|
||||
@ -53,7 +53,7 @@ pub struct SignUpPayloadPB {
|
||||
pub password: String,
|
||||
|
||||
#[pb(index = 4)]
|
||||
pub auth_type: AuthenticatorPB,
|
||||
pub auth_type: AuthTypePB,
|
||||
|
||||
#[pb(index = 5)]
|
||||
pub device_id: String,
|
||||
@ -144,7 +144,7 @@ pub struct OauthSignInPB {
|
||||
pub map: HashMap<String, String>,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub authenticator: AuthenticatorPB,
|
||||
pub authenticator: AuthTypePB,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default)]
|
||||
@ -153,7 +153,7 @@ pub struct SignInUrlPayloadPB {
|
||||
pub email: String,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub authenticator: AuthenticatorPB,
|
||||
pub authenticator: AuthTypePB,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default)]
|
||||
@ -228,41 +228,10 @@ pub struct OauthProviderDataPB {
|
||||
pub oauth_url: String,
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(ProtoBuf_Enum, Eq, PartialEq, Debug, Clone)]
|
||||
pub enum AuthenticatorPB {
|
||||
Local = 0,
|
||||
AppFlowyCloud = 2,
|
||||
}
|
||||
|
||||
impl From<AuthType> for AuthenticatorPB {
|
||||
fn from(auth_type: AuthType) -> Self {
|
||||
match auth_type {
|
||||
AuthType::Local => AuthenticatorPB::Local,
|
||||
AuthType::AppFlowyCloud => AuthenticatorPB::AppFlowyCloud,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AuthenticatorPB> for AuthType {
|
||||
fn from(pb: AuthenticatorPB) -> Self {
|
||||
match pb {
|
||||
AuthenticatorPB::Local => AuthType::Local,
|
||||
AuthenticatorPB::AppFlowyCloud => AuthType::AppFlowyCloud,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AuthenticatorPB {
|
||||
fn default() -> Self {
|
||||
Self::Local
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, ProtoBuf)]
|
||||
pub struct UserStatePB {
|
||||
#[pb(index = 1)]
|
||||
pub auth_type: AuthenticatorPB,
|
||||
pub auth_type: AuthTypePB,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Debug, Default, Clone)]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use super::AFRolePB;
|
||||
use crate::entities::parser::{UserEmail, UserIcon, UserName};
|
||||
use crate::entities::{AuthTypePB, AuthenticatorPB};
|
||||
use crate::entities::AuthTypePB;
|
||||
use crate::errors::ErrorCode;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_user_pub::entities::*;
|
||||
@ -39,7 +39,7 @@ pub struct UserProfilePB {
|
||||
pub icon_url: String,
|
||||
|
||||
#[pb(index = 6)]
|
||||
pub auth_type: AuthenticatorPB,
|
||||
pub auth_type: AuthTypePB,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf_Enum, Eq, PartialEq, Debug, Clone)]
|
||||
@ -186,7 +186,7 @@ pub struct UserWorkspacePB {
|
||||
pub role: Option<AFRolePB>,
|
||||
|
||||
#[pb(index = 7)]
|
||||
pub auth_type: AuthTypePB,
|
||||
pub workspace_auth_type: AuthTypePB,
|
||||
}
|
||||
|
||||
impl From<(AuthType, UserWorkspace)> for UserWorkspacePB {
|
||||
@ -198,7 +198,7 @@ impl From<(AuthType, UserWorkspace)> for UserWorkspacePB {
|
||||
icon: value.1.icon,
|
||||
member_count: value.1.member_count,
|
||||
role: value.1.role.map(AFRolePB::from),
|
||||
auth_type: AuthTypePB::from(value.0),
|
||||
workspace_auth_type: AuthTypePB::from(value.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,7 +212,7 @@ impl From<UserWorkspaceTable> for UserWorkspacePB {
|
||||
icon: value.icon,
|
||||
member_count: value.member_count,
|
||||
role: value.role.map(AFRolePB::from),
|
||||
auth_type: AuthTypePB::from(value.auth_type),
|
||||
workspace_auth_type: AuthTypePB::from(value.workspace_type),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,18 +242,20 @@ pub struct CreateWorkspacePB {
|
||||
pub auth_type: AuthTypePB,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf_Enum, Default, Debug, Clone)]
|
||||
#[derive(ProtoBuf_Enum, Default, Debug, Clone, Eq, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum AuthTypePB {
|
||||
LocalAuthType = 0,
|
||||
#[default]
|
||||
CloudAuthType = 1,
|
||||
Local = 0,
|
||||
Server = 1,
|
||||
}
|
||||
|
||||
impl From<i32> for AuthTypePB {
|
||||
fn from(value: i32) -> Self {
|
||||
match value {
|
||||
0 => AuthTypePB::LocalAuthType,
|
||||
1 => AuthTypePB::CloudAuthType,
|
||||
_ => AuthTypePB::CloudAuthType,
|
||||
0 => AuthTypePB::Local,
|
||||
1 => AuthTypePB::Server,
|
||||
_ => AuthTypePB::Server,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -261,8 +263,8 @@ impl From<i32> for AuthTypePB {
|
||||
impl From<AuthType> for AuthTypePB {
|
||||
fn from(value: AuthType) -> Self {
|
||||
match value {
|
||||
AuthType::Local => AuthTypePB::LocalAuthType,
|
||||
AuthType::AppFlowyCloud => AuthTypePB::CloudAuthType,
|
||||
AuthType::Local => AuthTypePB::Local,
|
||||
AuthType::AppFlowyCloud => AuthTypePB::Server,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -270,8 +272,8 @@ impl From<AuthType> for AuthTypePB {
|
||||
impl From<AuthTypePB> for AuthType {
|
||||
fn from(value: AuthTypePB) -> Self {
|
||||
match value {
|
||||
AuthTypePB::LocalAuthType => AuthType::Local,
|
||||
AuthTypePB::CloudAuthType => AuthType::AppFlowyCloud,
|
||||
AuthTypePB::Local => AuthType::Local,
|
||||
AuthTypePB::Server => AuthType::AppFlowyCloud,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,18 +44,12 @@ pub async fn sign_in_with_email_password_handler(
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let params: SignInParams = data.into_inner().try_into()?;
|
||||
|
||||
let old_authenticator = manager.cloud_service.get_server_auth_type();
|
||||
match manager
|
||||
.sign_in_with_password(¶ms.email, ¶ms.password)
|
||||
.await
|
||||
{
|
||||
Ok(token) => data_result_ok(token.into()),
|
||||
Err(err) => {
|
||||
manager
|
||||
.cloud_service
|
||||
.set_server_auth_type(&old_authenticator);
|
||||
return Err(err);
|
||||
},
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,13 +71,9 @@ pub async fn sign_up(
|
||||
let params: SignUpParams = data.into_inner().try_into()?;
|
||||
let auth_type = params.auth_type;
|
||||
|
||||
let prev_auth_type = manager.cloud_service.get_server_auth_type();
|
||||
match manager.sign_up(auth_type, BoxAny::new(params)).await {
|
||||
Ok(profile) => data_result_ok(UserProfilePB::from(profile)),
|
||||
Err(err) => {
|
||||
manager.cloud_service.set_server_auth_type(&prev_auth_type);
|
||||
Err(err)
|
||||
},
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
@ -485,7 +475,7 @@ pub async fn update_network_state_handler(
|
||||
.user_status_callback
|
||||
.read()
|
||||
.await
|
||||
.did_update_network(reachable);
|
||||
.on_network_status_changed(reachable);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@ -279,10 +279,9 @@ pub enum UserEvent {
|
||||
pub trait UserStatusCallback: Send + Sync + 'static {
|
||||
/// When the [AuthType] changed, this method will be called. Currently, the auth type
|
||||
/// will be changed when the user sign in or sign up.
|
||||
fn authenticator_did_changed(&self, _authenticator: AuthType) {}
|
||||
/// This will be called after the application launches if the user is already signed in.
|
||||
/// If the user is not signed in, this method will not be called
|
||||
async fn did_init(
|
||||
fn on_auth_type_changed(&self, _authenticator: AuthType) {}
|
||||
/// Fires on app launch, but only if the user is already signed in.
|
||||
async fn on_launch_if_authenticated(
|
||||
&self,
|
||||
_user_id: i64,
|
||||
_cloud_config: &Option<UserCloudConfig>,
|
||||
@ -292,8 +291,8 @@ pub trait UserStatusCallback: Send + Sync + 'static {
|
||||
) -> FlowyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// Will be called after the user signed in.
|
||||
async fn did_sign_in(
|
||||
/// Fires right after the user successfully signs in.
|
||||
async fn on_sign_in(
|
||||
&self,
|
||||
_user_id: i64,
|
||||
_user_workspace: &UserWorkspace,
|
||||
@ -302,8 +301,9 @@ pub trait UserStatusCallback: Send + Sync + 'static {
|
||||
) -> FlowyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
/// Will be called after the user signed up.
|
||||
async fn did_sign_up(
|
||||
|
||||
/// Fires right after the user successfully signs up.
|
||||
async fn on_sign_up(
|
||||
&self,
|
||||
_is_new_user: bool,
|
||||
_user_profile: &UserProfile,
|
||||
@ -314,10 +314,13 @@ pub trait UserStatusCallback: Send + Sync + 'static {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn did_expired(&self, _token: &str, _user_id: i64) -> FlowyResult<()> {
|
||||
/// Fires when an authentication token has expired.
|
||||
async fn on_token_expired(&self, _token: &str, _user_id: i64) -> FlowyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
async fn open_workspace(
|
||||
|
||||
/// Fires when a workspace is opened by the user.
|
||||
async fn on_workspace_opened(
|
||||
&self,
|
||||
_user_id: i64,
|
||||
_user_workspace: &UserWorkspace,
|
||||
@ -325,9 +328,9 @@ pub trait UserStatusCallback: Send + Sync + 'static {
|
||||
) -> FlowyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
fn did_update_network(&self, _reachable: bool) {}
|
||||
fn did_update_plans(&self, _plans: Vec<SubscriptionPlan>) {}
|
||||
fn did_update_storage_limitation(&self, _can_write: bool) {}
|
||||
fn on_network_status_changed(&self, _reachable: bool) {}
|
||||
fn on_subscription_plans_updated(&self, _plans: Vec<SubscriptionPlan>) {}
|
||||
fn on_storage_permission_updated(&self, _can_write: bool) {}
|
||||
}
|
||||
|
||||
/// Acts as a placeholder [UserStatusCallback] for the user session, but does not perform any function
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
use diesel::SqliteConnection;
|
||||
use semver::Version;
|
||||
use std::sync::Arc;
|
||||
use tracing::{info, instrument};
|
||||
|
||||
use collab_integrate::CollabKVDB;
|
||||
use flowy_error::FlowyResult;
|
||||
use flowy_user_pub::entities::AuthType;
|
||||
|
||||
use crate::migrations::migration::UserDataMigration;
|
||||
use flowy_user_pub::session::Session;
|
||||
use flowy_user_pub::sql::{select_user_workspace, upsert_user_workspace};
|
||||
|
||||
pub struct AnonUserWorkspaceTableMigration;
|
||||
|
||||
impl UserDataMigration for AnonUserWorkspaceTableMigration {
|
||||
fn name(&self) -> &str {
|
||||
"anon_user_workspace_table_migration"
|
||||
}
|
||||
|
||||
fn run_when(
|
||||
&self,
|
||||
first_installed_version: &Option<Version>,
|
||||
_current_version: &Version,
|
||||
) -> bool {
|
||||
match first_installed_version {
|
||||
None => true,
|
||||
Some(version) => version <= &Version::new(0, 8, 10),
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(name = "AnonUserWorkspaceTableMigration", skip_all, err)]
|
||||
fn run(
|
||||
&self,
|
||||
session: &Session,
|
||||
_collab_db: &Arc<CollabKVDB>,
|
||||
auth_type: &AuthType,
|
||||
db: &mut SqliteConnection,
|
||||
) -> FlowyResult<()> {
|
||||
// For historical reason, anon user doesn't have a workspace in user_workspace_table.
|
||||
// So we need to create a new entry for the anon user in the user_workspace_table.
|
||||
if matches!(auth_type, AuthType::Local) {
|
||||
let user_workspace = &session.user_workspace;
|
||||
let result = select_user_workspace(&user_workspace.id, db);
|
||||
if let Err(e) = result {
|
||||
if e.is_record_not_found() {
|
||||
info!(
|
||||
"Anon user workspace not found in the database, creating a new entry for user_id: {}",
|
||||
session.user_id
|
||||
);
|
||||
upsert_user_workspace(session.user_id, *auth_type, user_workspace.clone(), db)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use collab_plugins::local_storage::kv::doc::migrate_old_keys;
|
||||
use collab_plugins::local_storage::kv::KVTransactionDB;
|
||||
use diesel::SqliteConnection;
|
||||
use semver::Version;
|
||||
use tracing::{instrument, trace};
|
||||
|
||||
@ -40,6 +41,7 @@ impl UserDataMigration for CollabDocKeyWithWorkspaceIdMigration {
|
||||
session: &Session,
|
||||
collab_db: &Arc<CollabKVDB>,
|
||||
_authenticator: &AuthType,
|
||||
_db: &mut SqliteConnection,
|
||||
) -> FlowyResult<()> {
|
||||
trace!(
|
||||
"migrate key with workspace id:{}",
|
||||
|
||||
@ -6,6 +6,7 @@ use collab_document::document::Document;
|
||||
use collab_document::document_data::default_document_data;
|
||||
use collab_folder::{Folder, View};
|
||||
use collab_plugins::local_storage::kv::KVTransactionDB;
|
||||
use diesel::SqliteConnection;
|
||||
use semver::Version;
|
||||
use tracing::{event, instrument};
|
||||
|
||||
@ -42,6 +43,7 @@ impl UserDataMigration for HistoricalEmptyDocumentMigration {
|
||||
session: &Session,
|
||||
collab_db: &Arc<CollabKVDB>,
|
||||
authenticator: &AuthType,
|
||||
_db: &mut SqliteConnection,
|
||||
) -> FlowyResult<()> {
|
||||
// - The `empty document` struct has already undergone refactoring prior to the launch of the AppFlowy cloud version.
|
||||
// - Consequently, if a user is utilizing the AppFlowy cloud version, there is no need to perform any migration for the `empty document` struct.
|
||||
|
||||
@ -54,7 +54,7 @@ impl UserLocalDataMigration {
|
||||
pub fn run(
|
||||
self,
|
||||
migrations: Vec<Box<dyn UserDataMigration>>,
|
||||
authenticator: &AuthType,
|
||||
auth_type: &AuthType,
|
||||
app_version: &Version,
|
||||
) -> FlowyResult<Vec<String>> {
|
||||
let mut applied_migrations = vec![];
|
||||
@ -75,7 +75,7 @@ impl UserLocalDataMigration {
|
||||
|
||||
let migration_name = migration.name().to_string();
|
||||
if !duplicated_names.contains(&migration_name) {
|
||||
migration.run(&self.session, &self.collab_db, authenticator)?;
|
||||
migration.run(&self.session, &self.collab_db, auth_type, &mut conn)?;
|
||||
applied_migrations.push(migration.name().to_string());
|
||||
save_migration_record(&mut conn, &migration_name);
|
||||
duplicated_names.push(migration_name);
|
||||
@ -99,6 +99,7 @@ pub trait UserDataMigration {
|
||||
user: &Session,
|
||||
collab_db: &Arc<CollabKVDB>,
|
||||
authenticator: &AuthType,
|
||||
db: &mut SqliteConnection,
|
||||
) -> FlowyResult<()>;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use flowy_user_pub::session::Session;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub mod anon_user_workspace;
|
||||
pub mod doc_key_with_workspace;
|
||||
pub mod document_empty_content;
|
||||
pub mod migration;
|
||||
|
||||
@ -2,6 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use collab_folder::Folder;
|
||||
use collab_plugins::local_storage::kv::{KVTransactionDB, PersistenceError};
|
||||
use diesel::SqliteConnection;
|
||||
use semver::Version;
|
||||
use tracing::instrument;
|
||||
|
||||
@ -40,6 +41,7 @@ impl UserDataMigration for FavoriteV1AndWorkspaceArrayMigration {
|
||||
session: &Session,
|
||||
collab_db: &Arc<CollabKVDB>,
|
||||
_authenticator: &AuthType,
|
||||
_db: &mut SqliteConnection,
|
||||
) -> FlowyResult<()> {
|
||||
collab_db.with_write_txn(|write_txn| {
|
||||
if let Ok(collab) = load_collab(
|
||||
|
||||
@ -2,6 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use collab_folder::Folder;
|
||||
use collab_plugins::local_storage::kv::{KVTransactionDB, PersistenceError};
|
||||
use diesel::SqliteConnection;
|
||||
use semver::Version;
|
||||
use tracing::instrument;
|
||||
|
||||
@ -38,6 +39,7 @@ impl UserDataMigration for WorkspaceTrashMapToSectionMigration {
|
||||
session: &Session,
|
||||
collab_db: &Arc<CollabKVDB>,
|
||||
_authenticator: &AuthType,
|
||||
_db: &mut SqliteConnection,
|
||||
) -> FlowyResult<()> {
|
||||
collab_db.with_write_txn(|write_txn| {
|
||||
if let Ok(collab) = load_collab(
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use client_api::entity::GotrueTokenResponse;
|
||||
use collab_integrate::collab_builder::AppFlowyCollabBuilder;
|
||||
use collab_integrate::CollabKVDB;
|
||||
use flowy_error::{internal_error, ErrorCode, FlowyResult};
|
||||
use flowy_error::{internal_error, FlowyResult};
|
||||
|
||||
use arc_swap::ArcSwapOption;
|
||||
use collab::lock::RwLock;
|
||||
@ -21,7 +21,6 @@ use serde_json::Value;
|
||||
use std::string::ToString;
|
||||
use std::sync::atomic::{AtomicI64, Ordering};
|
||||
use std::sync::{Arc, Weak};
|
||||
use tokio::sync::Mutex;
|
||||
use tokio_stream::StreamExt;
|
||||
use tracing::{debug, error, event, info, instrument, warn};
|
||||
use uuid::Uuid;
|
||||
@ -39,8 +38,8 @@ use crate::services::authenticate_user::AuthenticateUser;
|
||||
use crate::services::cloud_config::get_cloud_config;
|
||||
use crate::services::collab_interact::{DefaultCollabInteract, UserReminder};
|
||||
|
||||
use crate::migrations::anon_user_workspace::AnonUserWorkspaceTableMigration;
|
||||
use crate::migrations::doc_key_with_workspace::CollabDocKeyWithWorkspaceIdMigration;
|
||||
use crate::user_manager::user_login_state::UserAuthProcess;
|
||||
use crate::{errors::FlowyError, notification::*};
|
||||
use flowy_user_pub::session::Session;
|
||||
use flowy_user_pub::sql::*;
|
||||
@ -53,7 +52,6 @@ pub struct UserManager {
|
||||
pub(crate) collab_builder: Weak<AppFlowyCollabBuilder>,
|
||||
pub(crate) collab_interact: RwLock<Arc<dyn UserReminder>>,
|
||||
pub(crate) user_workspace_service: Arc<dyn UserWorkspaceService>,
|
||||
auth_process: Mutex<Option<UserAuthProcess>>,
|
||||
pub(crate) authenticate_user: Arc<AuthenticateUser>,
|
||||
refresh_user_profile_since: AtomicI64,
|
||||
pub(crate) is_loading_awareness: Arc<DashMap<Uuid, bool>>,
|
||||
@ -78,7 +76,6 @@ impl UserManager {
|
||||
user_status_callback,
|
||||
collab_builder,
|
||||
collab_interact: RwLock::new(Arc::new(DefaultCollabInteract)),
|
||||
auth_process: Default::default(),
|
||||
authenticate_user,
|
||||
refresh_user_profile_since,
|
||||
user_workspace_service,
|
||||
@ -132,18 +129,19 @@ impl UserManager {
|
||||
|
||||
if let Ok(session) = self.get_session() {
|
||||
let user = self.get_user_profile_from_disk(session.user_id).await?;
|
||||
self.cloud_service.set_server_auth_type(&user.auth_type);
|
||||
|
||||
// Get the current authenticator from the environment variable
|
||||
let current_authenticator = current_authenticator();
|
||||
let env_auth_type = current_authenticator();
|
||||
|
||||
// If the current authenticator is different from the authenticator in the session and it's
|
||||
// not a local authenticator, we need to sign out the user.
|
||||
if user.auth_type != AuthType::Local && user.auth_type != current_authenticator {
|
||||
if user.auth_type != AuthType::Local && user.auth_type != env_auth_type {
|
||||
event!(
|
||||
tracing::Level::INFO,
|
||||
"Authenticator changed from {:?} to {:?}",
|
||||
"Auth type changed from {:?} to {:?}",
|
||||
user.auth_type,
|
||||
current_authenticator
|
||||
env_auth_type
|
||||
);
|
||||
self.sign_out().await?;
|
||||
return Ok(());
|
||||
@ -151,7 +149,7 @@ impl UserManager {
|
||||
|
||||
event!(
|
||||
tracing::Level::INFO,
|
||||
"init user session: {}:{}, authenticator: {:?}",
|
||||
"init user session: {}:{}, auth type: {:?}",
|
||||
user.uid,
|
||||
user.email,
|
||||
user.auth_type,
|
||||
@ -269,7 +267,7 @@ impl UserManager {
|
||||
let _ = self.initial_user_awareness(&session, &user.auth_type).await;
|
||||
|
||||
user_status_callback
|
||||
.did_init(
|
||||
.on_launch_if_authenticated(
|
||||
user.uid,
|
||||
&cloud_config,
|
||||
&session.user_workspace,
|
||||
@ -362,7 +360,7 @@ impl UserManager {
|
||||
.user_status_callback
|
||||
.read()
|
||||
.await
|
||||
.did_sign_in(
|
||||
.on_sign_in(
|
||||
user_profile.uid,
|
||||
&latest_workspace,
|
||||
&self.authenticate_user.user_config.device_id,
|
||||
@ -389,9 +387,10 @@ impl UserManager {
|
||||
auth_type: AuthType,
|
||||
params: BoxAny,
|
||||
) -> Result<UserProfile, FlowyError> {
|
||||
self.cloud_service.set_server_auth_type(&auth_type);
|
||||
|
||||
// sign out the current user if there is one
|
||||
let migration_user = self.get_migration_user(&auth_type).await;
|
||||
self.cloud_service.set_server_auth_type(&auth_type);
|
||||
let auth_service = self.cloud_service.get_user_service()?;
|
||||
let response: AuthResponse = auth_service.sign_up(params).await?;
|
||||
let new_user_profile = UserProfile::from((&response, &auth_type));
|
||||
@ -401,28 +400,6 @@ impl UserManager {
|
||||
Ok(new_user_profile)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "info", skip(self))]
|
||||
pub async fn resume_sign_up(&self) -> Result<(), FlowyError> {
|
||||
let UserAuthProcess {
|
||||
user_profile,
|
||||
migration_user,
|
||||
response,
|
||||
authenticator,
|
||||
} = self
|
||||
.auth_process
|
||||
.lock()
|
||||
.await
|
||||
.clone()
|
||||
.ok_or(FlowyError::new(
|
||||
ErrorCode::Internal,
|
||||
"No resumable sign up data",
|
||||
))?;
|
||||
self
|
||||
.continue_sign_up(&user_profile, migration_user, response, &authenticator)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "info", skip_all, err)]
|
||||
async fn continue_sign_up(
|
||||
&self,
|
||||
@ -436,14 +413,12 @@ impl UserManager {
|
||||
self
|
||||
.save_auth_data(&response, *auth_type, &new_session)
|
||||
.await?;
|
||||
let _ = self
|
||||
.initial_user_awareness(&new_session, &new_user_profile.auth_type)
|
||||
.await;
|
||||
let _ = self.initial_user_awareness(&new_session, auth_type).await;
|
||||
self
|
||||
.user_status_callback
|
||||
.read()
|
||||
.await
|
||||
.did_sign_up(
|
||||
.on_sign_up(
|
||||
response.is_new_user,
|
||||
new_user_profile,
|
||||
&new_session.user_workspace,
|
||||
@ -670,6 +645,7 @@ impl UserManager {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "info", skip_all)]
|
||||
pub(crate) async fn generate_sign_in_url_with_email(
|
||||
&self,
|
||||
authenticator: &AuthType,
|
||||
@ -682,6 +658,7 @@ impl UserManager {
|
||||
Ok(url)
|
||||
}
|
||||
|
||||
#[instrument(level = "info", skip_all)]
|
||||
pub(crate) async fn sign_in_with_password(
|
||||
&self,
|
||||
email: &str,
|
||||
@ -695,6 +672,7 @@ impl UserManager {
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
#[instrument(level = "info", skip_all)]
|
||||
pub(crate) async fn sign_in_with_magic_link(
|
||||
&self,
|
||||
email: &str,
|
||||
@ -710,6 +688,7 @@ impl UserManager {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(level = "info", skip_all)]
|
||||
pub(crate) async fn sign_in_with_passcode(
|
||||
&self,
|
||||
email: &str,
|
||||
@ -723,6 +702,7 @@ impl UserManager {
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
#[instrument(level = "info", skip_all)]
|
||||
pub(crate) async fn generate_oauth_url(
|
||||
&self,
|
||||
oauth_provider: &str,
|
||||
@ -870,6 +850,7 @@ fn collab_migration_list() -> Vec<Box<dyn UserDataMigration>> {
|
||||
Box::new(FavoriteV1AndWorkspaceArrayMigration),
|
||||
Box::new(WorkspaceTrashMapToSectionMigration),
|
||||
Box::new(CollabDocKeyWithWorkspaceIdMigration),
|
||||
Box::new(AnonUserWorkspaceTableMigration),
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -154,9 +154,11 @@ impl UserManager {
|
||||
#[instrument(skip(self), err)]
|
||||
pub async fn open_workspace(&self, workspace_id: &Uuid, auth_type: AuthType) -> FlowyResult<()> {
|
||||
info!("open workspace: {}, auth_type:{}", workspace_id, auth_type);
|
||||
self.cloud_service.set_server_auth_type(&auth_type);
|
||||
|
||||
let uid = self.user_id()?;
|
||||
let conn = self.db_connection(self.user_id()?)?;
|
||||
let user_workspace = match select_user_workspace(&workspace_id.to_string(), conn) {
|
||||
let mut conn = self.db_connection(self.user_id()?)?;
|
||||
let user_workspace = match select_user_workspace(&workspace_id.to_string(), &mut conn) {
|
||||
Err(err) => {
|
||||
if err.is_record_not_found() {
|
||||
sync_workspace(
|
||||
@ -193,7 +195,7 @@ impl UserManager {
|
||||
.user_status_callback
|
||||
.read()
|
||||
.await
|
||||
.open_workspace(uid, &user_workspace, &user_profile.auth_type)
|
||||
.on_workspace_opened(uid, &user_workspace, &user_profile.auth_type)
|
||||
.await
|
||||
{
|
||||
error!("Open workspace failed: {:?}", err);
|
||||
@ -218,15 +220,23 @@ impl UserManager {
|
||||
workspace_name: &str,
|
||||
auth_type: AuthType,
|
||||
) -> FlowyResult<UserWorkspace> {
|
||||
let new_workspace = self
|
||||
.cloud_service
|
||||
.get_user_service()?
|
||||
.create_workspace(workspace_name)
|
||||
.await?;
|
||||
let new_workspace = match auth_type {
|
||||
AuthType::Local => {
|
||||
let workspace_id = Uuid::new_v4();
|
||||
UserWorkspace::new_local(workspace_id.to_string(), workspace_name)
|
||||
},
|
||||
AuthType::AppFlowyCloud => {
|
||||
self
|
||||
.cloud_service
|
||||
.get_user_service()?
|
||||
.create_workspace(workspace_name)
|
||||
.await?
|
||||
},
|
||||
};
|
||||
|
||||
info!(
|
||||
"new workspace: {}, name:{}",
|
||||
new_workspace.id, new_workspace.name
|
||||
"create workspace: {}, name:{}, auth_type: {}",
|
||||
new_workspace.id, new_workspace.name, auth_type
|
||||
);
|
||||
|
||||
// save the workspace to sqlite db
|
||||
@ -391,8 +401,8 @@ impl UserManager {
|
||||
uid: i64,
|
||||
workspace_id: &Uuid,
|
||||
) -> FlowyResult<UserWorkspaceTable> {
|
||||
let conn = self.db_connection(uid)?;
|
||||
select_user_workspace(workspace_id.to_string().as_str(), conn)
|
||||
let mut conn = self.db_connection(uid)?;
|
||||
select_user_workspace(workspace_id.to_string().as_str(), &mut conn)
|
||||
}
|
||||
|
||||
pub async fn get_all_user_workspaces(
|
||||
@ -522,7 +532,7 @@ impl UserManager {
|
||||
.user_status_callback
|
||||
.read()
|
||||
.await
|
||||
.did_update_storage_limitation(can_write);
|
||||
.on_storage_permission_updated(can_write);
|
||||
|
||||
Ok(workspace_usage)
|
||||
}
|
||||
@ -683,7 +693,7 @@ impl UserManager {
|
||||
.user_status_callback
|
||||
.read()
|
||||
.await
|
||||
.did_update_plans(plans);
|
||||
.on_subscription_plans_updated(plans);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,5 @@ pub(crate) mod manager_history_user;
|
||||
pub(crate) mod manager_user_awareness;
|
||||
pub(crate) mod manager_user_encryption;
|
||||
pub(crate) mod manager_user_workspace;
|
||||
mod user_login_state;
|
||||
|
||||
pub use manager::*;
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
use crate::migrations::AnonUser;
|
||||
use flowy_user_pub::entities::{AuthResponse, AuthType, UserProfile};
|
||||
|
||||
/// recording the intermediate state of the sign-in/sign-up process
|
||||
#[derive(Clone)]
|
||||
pub struct UserAuthProcess {
|
||||
pub user_profile: UserProfile,
|
||||
pub response: AuthResponse,
|
||||
pub authenticator: AuthType,
|
||||
pub migration_user: Option<AnonUser>,
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user