| 
									
										
										
										
											2023-08-07 16:54:50 +07:00
										 |  |  | import 'dart:async'; | 
					
						
							|  |  |  | import 'dart:io'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-25 01:18:31 -08:00
										 |  |  | import 'package:appflowy/env/cloud_env.dart'; | 
					
						
							| 
									
										
										
										
											2023-08-12 17:36:31 +08:00
										 |  |  | import 'package:appflowy/user/application/supabase_realtime.dart'; | 
					
						
							| 
									
										
										
										
											2023-08-07 13:31:20 +07:00
										 |  |  | import 'package:appflowy/workspace/application/settings/application_data_storage.dart'; | 
					
						
							|  |  |  | import 'package:flutter/foundation.dart'; | 
					
						
							|  |  |  | import 'package:hive_flutter/hive_flutter.dart'; | 
					
						
							|  |  |  | import 'package:path/path.dart' as p; | 
					
						
							| 
									
										
										
										
											2023-11-17 13:51:26 +08:00
										 |  |  | import 'package:supabase_flutter/supabase_flutter.dart'; | 
					
						
							|  |  |  | import 'package:url_protocol/url_protocol.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-21 18:53:59 +08:00
										 |  |  | import '../startup.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-07 16:54:50 +07:00
										 |  |  | // ONLY supports in macOS and Windows now.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // If you need to update the schema, please update the following files:
 | 
					
						
							|  |  |  | // - appflowy_flutter/macos/Runner/Info.plist (macOS)
 | 
					
						
							|  |  |  | // - the callback url in Supabase dashboard
 | 
					
						
							|  |  |  | const appflowyDeepLinkSchema = 'appflowy-flutter'; | 
					
						
							|  |  |  | const supabaseLoginCallback = '$appflowyDeepLinkSchema://login-callback'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-07 13:31:20 +07:00
										 |  |  | const hiveBoxName = 'appflowy_supabase_authentication'; | 
					
						
							| 
									
										
										
										
											2023-05-21 18:53:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-07 16:54:50 +07:00
										 |  |  | // Used to store the session of the supabase in case of the user switch the different folder.
 | 
					
						
							|  |  |  | Supabase? supabase; | 
					
						
							| 
									
										
										
										
											2023-11-23 23:32:52 +08:00
										 |  |  | SupabaseRealtimeService? realtimeService; | 
					
						
							| 
									
										
										
										
											2023-08-07 16:54:50 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-21 18:53:59 +08:00
										 |  |  | class InitSupabaseTask extends LaunchTask { | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Future<void> initialize(LaunchContext context) async { | 
					
						
							| 
									
										
										
										
											2023-10-07 09:58:44 +08:00
										 |  |  |     if (!isSupabaseEnabled) { | 
					
						
							| 
									
										
										
										
											2023-05-21 18:53:59 +08:00
										 |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-07-05 20:57:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-30 16:05:56 +08:00
										 |  |  |     await supabase?.dispose(); | 
					
						
							| 
									
										
										
										
											2023-08-07 16:54:50 +07:00
										 |  |  |     supabase = null; | 
					
						
							| 
									
										
										
										
											2023-08-12 17:36:31 +08:00
										 |  |  |     final initializedSupabase = await Supabase.initialize( | 
					
						
							| 
									
										
										
										
											2023-11-24 11:54:47 +08:00
										 |  |  |       url: getIt<AppFlowyCloudSharedEnv>().supabaseConfig.url, | 
					
						
							|  |  |  |       anonKey: getIt<AppFlowyCloudSharedEnv>().supabaseConfig.anon_key, | 
					
						
							| 
									
										
										
										
											2023-08-07 13:31:20 +07:00
										 |  |  |       debug: kDebugMode, | 
					
						
							| 
									
										
										
										
											2024-01-30 16:05:56 +08:00
										 |  |  |       authOptions: const FlutterAuthClientOptions( | 
					
						
							|  |  |  |         localStorage: SupabaseLocalStorage(), | 
					
						
							|  |  |  |       ), | 
					
						
							| 
									
										
										
										
											2023-05-21 18:53:59 +08:00
										 |  |  |     ); | 
					
						
							| 
									
										
										
										
											2023-08-20 14:13:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (realtimeService != null) { | 
					
						
							|  |  |  |       await realtimeService?.dispose(); | 
					
						
							|  |  |  |       realtimeService = null; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-11-23 23:32:52 +08:00
										 |  |  |     realtimeService = SupabaseRealtimeService(supabase: initializedSupabase); | 
					
						
							| 
									
										
										
										
											2023-08-31 16:40:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-12 17:36:31 +08:00
										 |  |  |     supabase = initializedSupabase; | 
					
						
							| 
									
										
										
										
											2023-08-14 21:38:30 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (Platform.isWindows) { | 
					
						
							|  |  |  |       // register deep link for Windows
 | 
					
						
							|  |  |  |       registerProtocolHandler(appflowyDeepLinkSchema); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-08-07 13:31:20 +07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-10-24 23:13:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Future<void> dispose() async { | 
					
						
							|  |  |  |     await realtimeService?.dispose(); | 
					
						
							| 
									
										
										
										
											2023-11-17 13:51:26 +08:00
										 |  |  |     realtimeService = null; | 
					
						
							| 
									
										
										
										
											2024-01-30 16:05:56 +08:00
										 |  |  |     await supabase?.dispose(); | 
					
						
							| 
									
										
										
										
											2023-11-17 13:51:26 +08:00
										 |  |  |     supabase = null; | 
					
						
							| 
									
										
										
										
											2023-10-24 23:13:51 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-08-07 13:31:20 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// customize the supabase auth storage
 | 
					
						
							|  |  |  | ///
 | 
					
						
							|  |  |  | /// We don't use the default one because it always save the session in the document directory.
 | 
					
						
							|  |  |  | /// When we switch to the different folder, the session still exists.
 | 
					
						
							|  |  |  | class SupabaseLocalStorage extends LocalStorage { | 
					
						
							| 
									
										
										
										
											2024-01-30 16:05:56 +08:00
										 |  |  |   const SupabaseLocalStorage(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Future<void> initialize() async { | 
					
						
							| 
									
										
										
										
											2023-08-07 13:31:20 +07:00
										 |  |  |     HiveCipher? encryptionCipher; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // customize the path for Hive
 | 
					
						
							|  |  |  |     final path = await getIt<ApplicationDataStorage>().getPath(); | 
					
						
							|  |  |  |     Hive.init(p.join(path, 'supabase_auth')); | 
					
						
							|  |  |  |     await Hive.openBox( | 
					
						
							|  |  |  |       hiveBoxName, | 
					
						
							|  |  |  |       encryptionCipher: encryptionCipher, | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-30 16:05:56 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Future<bool> hasAccessToken() { | 
					
						
							| 
									
										
										
										
											2023-08-07 13:31:20 +07:00
										 |  |  |     return Future.value( | 
					
						
							|  |  |  |       Hive.box(hiveBoxName).containsKey( | 
					
						
							|  |  |  |         supabasePersistSessionKey, | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-30 16:05:56 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Future<String?> accessToken() { | 
					
						
							| 
									
										
										
										
											2023-08-07 13:31:20 +07:00
										 |  |  |     return Future.value( | 
					
						
							|  |  |  |       Hive.box(hiveBoxName).get(supabasePersistSessionKey) as String?, | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-30 16:05:56 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Future<void> removePersistedSession() { | 
					
						
							| 
									
										
										
										
											2023-08-07 13:31:20 +07:00
										 |  |  |     return Hive.box(hiveBoxName).delete(supabasePersistSessionKey); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-07-05 20:57:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-30 16:05:56 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Future<void> persistSession(String persistSessionString) { | 
					
						
							| 
									
										
										
										
											2023-08-07 13:31:20 +07:00
										 |  |  |     return Hive.box(hiveBoxName).put( | 
					
						
							|  |  |  |       supabasePersistSessionKey, | 
					
						
							|  |  |  |       persistSessionString, | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2023-05-21 18:53:59 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } |