Skip to content

Commit 9500abb

Browse files
authored
feat: workspace service in user crate (#4373)
* refactor: user manager * feat: implement workspace service * refactor: migrate user data when sign up * chore: fmt * chore: enable beta cloud * chore: update ci * chore: trim slash
1 parent 690a374 commit 9500abb

File tree

66 files changed

+881
-1081
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+881
-1081
lines changed

.github/workflows/flutter_ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ on:
2222
env:
2323
CARGO_TERM_COLOR: always
2424
FLUTTER_VERSION: "3.18.0-0.2.pre"
25-
RUST_TOOLCHAIN: "1.70"
25+
RUST_TOOLCHAIN: "1.75"
2626
CARGO_MAKE_VERSION: "0.36.6"
2727

2828
concurrency:

frontend/appflowy_flutter/integration_test/cloud/anon_user_continue_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ void main() {
2626
group('appflowy cloud', () {
2727
testWidgets('anon user and then sign in', (tester) async {
2828
await tester.initializeAppFlowy(
29-
cloudType: AuthenticatorType.appflowyCloud,
29+
cloudType: AuthenticatorType.appflowyCloudSelfHost,
3030
);
3131

3232
tester.expectToSeeText(LocaleKeys.signIn_loginStartWithAnonymous.tr());

frontend/appflowy_flutter/integration_test/cloud/appflowy_cloud_auth_test.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ void main() {
2222
group('appflowy cloud auth', () {
2323
testWidgets('sign in', (tester) async {
2424
await tester.initializeAppFlowy(
25-
cloudType: AuthenticatorType.appflowyCloud,
25+
cloudType: AuthenticatorType.appflowyCloudSelfHost,
2626
);
2727
await tester.tapGoogleLoginInButton();
2828
await tester.expectToSeeHomePageWithGetStartedPage();
2929
});
3030

3131
testWidgets('sign out', (tester) async {
3232
await tester.initializeAppFlowy(
33-
cloudType: AuthenticatorType.appflowyCloud,
33+
cloudType: AuthenticatorType.appflowyCloudSelfHost,
3434
);
3535
await tester.tapGoogleLoginInButton();
3636

@@ -49,7 +49,7 @@ void main() {
4949

5050
testWidgets('sign in as annoymous', (tester) async {
5151
await tester.initializeAppFlowy(
52-
cloudType: AuthenticatorType.appflowyCloud,
52+
cloudType: AuthenticatorType.appflowyCloudSelfHost,
5353
);
5454
await tester.tapSignInAsGuest();
5555

@@ -61,7 +61,7 @@ void main() {
6161

6262
testWidgets('enable sync', (tester) async {
6363
await tester.initializeAppFlowy(
64-
cloudType: AuthenticatorType.appflowyCloud,
64+
cloudType: AuthenticatorType.appflowyCloudSelfHost,
6565
);
6666

6767
await tester.tapGoogleLoginInButton();

frontend/appflowy_flutter/integration_test/cloud/document_sync_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void main() {
3131
group('appflowy cloud document', () {
3232
testWidgets('sync local docuemnt to server', (tester) async {
3333
await tester.initializeAppFlowy(
34-
cloudType: AuthenticatorType.appflowyCloud,
34+
cloudType: AuthenticatorType.appflowyCloudSelfHost,
3535
email: email,
3636
);
3737
await tester.tapGoogleLoginInButton();
@@ -58,7 +58,7 @@ void main() {
5858

5959
testWidgets('sync doc from server', (tester) async {
6060
await tester.initializeAppFlowy(
61-
cloudType: AuthenticatorType.appflowyCloud,
61+
cloudType: AuthenticatorType.appflowyCloudSelfHost,
6262
email: email,
6363
);
6464
await tester.tapGoogleLoginInButton();

frontend/appflowy_flutter/integration_test/cloud/empty_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ void main() {
1111
group('Empty', () {
1212
testWidgets('set appflowy cloud', (tester) async {
1313
await tester.initializeAppFlowy(
14-
cloudType: AuthenticatorType.appflowyCloud,
14+
cloudType: AuthenticatorType.appflowyCloudSelfHost,
1515
);
1616
});
1717
});

frontend/appflowy_flutter/integration_test/cloud/user_setting_sync_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ void main() {
3232
group('appflowy cloud setting', () {
3333
testWidgets('sync user name and icon to server', (tester) async {
3434
await tester.initializeAppFlowy(
35-
cloudType: AuthenticatorType.appflowyCloud,
35+
cloudType: AuthenticatorType.appflowyCloudSelfHost,
3636
email: email,
3737
);
3838
await tester.tapGoogleLoginInButton();
@@ -70,7 +70,7 @@ void main() {
7070

7171
testWidgets('get user icon and name from server', (tester) async {
7272
await tester.initializeAppFlowy(
73-
cloudType: AuthenticatorType.appflowyCloud,
73+
cloudType: AuthenticatorType.appflowyCloudSelfHost,
7474
email: email,
7575
);
7676
await tester.tapGoogleLoginInButton();

frontend/appflowy_flutter/integration_test/util/base.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ extension AppFlowyTestBase on WidgetTester {
6363
rustEnvs["GOTRUE_ADMIN_EMAIL"] = "[email protected]";
6464
rustEnvs["GOTRUE_ADMIN_PASSWORD"] = "password";
6565
break;
66+
case AuthenticatorType.appflowyCloudSelfHost:
67+
rustEnvs["GOTRUE_ADMIN_EMAIL"] = "[email protected]";
68+
rustEnvs["GOTRUE_ADMIN_PASSWORD"] = "password";
69+
break;
6670
}
6771
}
6872
return rustEnvs;
@@ -89,6 +93,13 @@ extension AppFlowyTestBase on WidgetTester {
8993
() => AppFlowyCloudMockAuthService(email: email),
9094
);
9195
break;
96+
case AuthenticatorType.appflowyCloudSelfHost:
97+
await useAppFlowyCloud();
98+
getIt.unregister<AuthService>();
99+
getIt.registerFactory<AuthService>(
100+
() => AppFlowyCloudMockAuthService(email: email),
101+
);
102+
break;
92103
}
93104
}
94105
},
@@ -258,7 +269,7 @@ Future<void> useSupabaseCloud() async {
258269
}
259270

260271
Future<void> useAppFlowyCloud() async {
261-
await setAuthenticatorType(AuthenticatorType.appflowyCloud);
272+
await setAuthenticatorType(AuthenticatorType.appflowyCloudSelfHost);
262273
await setAppFlowyCloudUrl(Some(TestEnv.afCloudUrl));
263274
}
264275

frontend/appflowy_flutter/lib/env/cloud_env.dart

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ Future<void> setAuthenticatorType(AuthenticatorType ty) async {
2828
case AuthenticatorType.appflowyCloud:
2929
getIt<KeyValueStorage>().set(KVKeys.kCloudType, 2.toString());
3030
break;
31+
case AuthenticatorType.appflowyCloudSelfHost:
32+
getIt<KeyValueStorage>().set(KVKeys.kCloudType, 3.toString());
33+
break;
3134
}
3235
}
3336

@@ -52,6 +55,8 @@ Future<AuthenticatorType> getAuthenticatorType() async {
5255
return AuthenticatorType.supabase;
5356
case "2":
5457
return AuthenticatorType.appflowyCloud;
58+
case "3":
59+
return AuthenticatorType.appflowyCloudSelfHost;
5560
default:
5661
return AuthenticatorType.local;
5762
}
@@ -75,7 +80,8 @@ bool get isAuthEnabled {
7580
return env.supabaseConfig.isValid;
7681
}
7782

78-
if (env.authenticatorType == AuthenticatorType.appflowyCloud) {
83+
if (env.authenticatorType == AuthenticatorType.appflowyCloudSelfHost ||
84+
env.authenticatorType == AuthenticatorType.appflowyCloud) {
7985
return env.appflowyCloudConfig.isValid;
8086
}
8187

@@ -92,20 +98,28 @@ bool get isAuthEnabled {
9298
/// if the application is in release or develop mode and the current cloud type
9399
/// is `CloudType.supabase`. Otherwise, it returns `false`.
94100
bool get isSupabaseEnabled {
95-
return currentCloudType() == AuthenticatorType.supabase;
101+
return currentCloudType().isSupabaseEnabled;
96102
}
97103

98104
/// Determines if AppFlowy Cloud is enabled.
99105
bool get isAppFlowyCloudEnabled {
100-
return currentCloudType() == AuthenticatorType.appflowyCloud;
106+
return currentCloudType().isAppFlowyCloudEnabled;
101107
}
102108

103109
enum AuthenticatorType {
104110
local,
105111
supabase,
106-
appflowyCloud;
112+
appflowyCloud,
113+
appflowyCloudSelfHost;
107114

108115
bool get isLocal => this == AuthenticatorType.local;
116+
117+
bool get isAppFlowyCloudEnabled =>
118+
this == AuthenticatorType.appflowyCloudSelfHost ||
119+
this == AuthenticatorType.appflowyCloud;
120+
121+
bool get isSupabaseEnabled => this == AuthenticatorType.supabase;
122+
109123
int get value {
110124
switch (this) {
111125
case AuthenticatorType.local:
@@ -114,6 +128,8 @@ enum AuthenticatorType {
114128
return 1;
115129
case AuthenticatorType.appflowyCloud:
116130
return 2;
131+
case AuthenticatorType.appflowyCloudSelfHost:
132+
return 3;
117133
}
118134
}
119135

@@ -125,6 +141,8 @@ enum AuthenticatorType {
125141
return AuthenticatorType.supabase;
126142
case 2:
127143
return AuthenticatorType.appflowyCloud;
144+
case 3:
145+
return AuthenticatorType.appflowyCloudSelfHost;
128146
default:
129147
return AuthenticatorType.local;
130148
}
@@ -160,7 +178,17 @@ class AppFlowyCloudSharedEnv {
160178
// If [Env.enableCustomCloud] is true, then use the custom cloud configuration.
161179
if (Env.enableCustomCloud) {
162180
// Use the custom cloud configuration.
163-
final cloudType = await getAuthenticatorType();
181+
var cloudType = await getAuthenticatorType();
182+
183+
// In the backend, the value '2' represents the use of AppFlowy Cloud. However, in the frontend,
184+
// we distinguish between [AuthenticatorType.appflowyCloudSelfHost] and [AuthenticatorType.appflowyCloud].
185+
// When the cloud type is [AuthenticatorType.appflowyCloudSelfHost] in the frontend, it should be
186+
// converted to [AuthenticatorType.appflowyCloud] to align with the backend representation,
187+
// where both types are indicated by the value '2'.
188+
if (cloudType == AuthenticatorType.appflowyCloudSelfHost) {
189+
cloudType = AuthenticatorType.appflowyCloud;
190+
}
191+
164192
final appflowyCloudConfig = cloudType.isLocal
165193
? AppFlowyCloudConfiguration.defaultConfig()
166194
: await getAppFlowyCloudConfig();

frontend/appflowy_flutter/lib/env/env.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ part 'env.g.dart';
88
abstract class Env {
99
// This flag is used to decide if users can dynamically configure cloud settings. It turns true when a .env file exists containing the APPFLOWY_CLOUD_URL variable. By default, this is set to false.
1010
static bool get enableCustomCloud {
11-
return Env.authenticatorType == AuthenticatorType.appflowyCloud.value &&
12-
_Env.afCloudUrl.isEmpty;
11+
return Env.authenticatorType ==
12+
AuthenticatorType.appflowyCloudSelfHost.value ||
13+
Env.authenticatorType == AuthenticatorType.appflowyCloud.value &&
14+
_Env.afCloudUrl.isEmpty;
1315
}
1416

1517
@EnviedField(

frontend/appflowy_flutter/lib/startup/deps_resolver.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class DependencyResolver {
5656

5757
Future<void> _resolveCloudDeps(GetIt getIt) async {
5858
final env = await AppFlowyCloudSharedEnv.fromEnv();
59-
Log.info("cloud setting: \n$env");
59+
Log.info("cloud setting: $env");
6060
getIt.registerFactory<AppFlowyCloudSharedEnv>(() => env);
6161

6262
if (isAppFlowyCloudEnabled) {
@@ -141,6 +141,7 @@ void _resolveUserDeps(GetIt getIt, IntegrationMode mode) {
141141
getIt.registerFactory<AuthService>(() => SupabaseAuthService());
142142
break;
143143
case AuthenticatorType.appflowyCloud:
144+
case AuthenticatorType.appflowyCloudSelfHost:
144145
getIt.registerFactory<AuthService>(() => AppFlowyCloudAuthService());
145146
break;
146147
}

0 commit comments

Comments
 (0)