supabase_task.dart 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import 'dart:async';
  2. import 'dart:io';
  3. import 'package:appflowy/env/env.dart';
  4. import 'package:appflowy/workspace/application/settings/application_data_storage.dart';
  5. import 'package:flutter/foundation.dart';
  6. import 'package:supabase_flutter/supabase_flutter.dart';
  7. import 'package:url_protocol/url_protocol.dart';
  8. import 'package:hive_flutter/hive_flutter.dart';
  9. import 'package:path/path.dart' as p;
  10. import '../startup.dart';
  11. // ONLY supports in macOS and Windows now.
  12. //
  13. // If you need to update the schema, please update the following files:
  14. // - appflowy_flutter/macos/Runner/Info.plist (macOS)
  15. // - the callback url in Supabase dashboard
  16. const appflowyDeepLinkSchema = 'appflowy-flutter';
  17. const supabaseLoginCallback = '$appflowyDeepLinkSchema://login-callback';
  18. const hiveBoxName = 'appflowy_supabase_authentication';
  19. // Used to store the session of the supabase in case of the user switch the different folder.
  20. Supabase? supabase;
  21. class InitSupabaseTask extends LaunchTask {
  22. @override
  23. Future<void> initialize(LaunchContext context) async {
  24. if (!isSupabaseEnabled) {
  25. return;
  26. }
  27. // register deep link for Windows
  28. if (Platform.isWindows) {
  29. registerProtocolHandler(appflowyDeepLinkSchema);
  30. }
  31. supabase?.dispose();
  32. supabase = null;
  33. supabase = await Supabase.initialize(
  34. url: Env.supabaseUrl,
  35. anonKey: Env.supabaseAnonKey,
  36. debug: kDebugMode,
  37. localStorage: const SupabaseLocalStorage(),
  38. );
  39. }
  40. }
  41. /// customize the supabase auth storage
  42. ///
  43. /// We don't use the default one because it always save the session in the document directory.
  44. /// When we switch to the different folder, the session still exists.
  45. class SupabaseLocalStorage extends LocalStorage {
  46. const SupabaseLocalStorage()
  47. : super(
  48. initialize: _initialize,
  49. hasAccessToken: _hasAccessToken,
  50. accessToken: _accessToken,
  51. removePersistedSession: _removePersistedSession,
  52. persistSession: _persistSession,
  53. );
  54. static Future<void> _initialize() async {
  55. HiveCipher? encryptionCipher;
  56. // customize the path for Hive
  57. final path = await getIt<ApplicationDataStorage>().getPath();
  58. Hive.init(p.join(path, 'supabase_auth'));
  59. await Hive.openBox(
  60. hiveBoxName,
  61. encryptionCipher: encryptionCipher,
  62. );
  63. }
  64. static Future<bool> _hasAccessToken() {
  65. return Future.value(
  66. Hive.box(hiveBoxName).containsKey(
  67. supabasePersistSessionKey,
  68. ),
  69. );
  70. }
  71. static Future<String?> _accessToken() {
  72. return Future.value(
  73. Hive.box(hiveBoxName).get(supabasePersistSessionKey) as String?,
  74. );
  75. }
  76. static Future<void> _removePersistedSession() {
  77. return Hive.box(hiveBoxName).delete(supabasePersistSessionKey);
  78. }
  79. static Future<void> _persistSession(String persistSessionString) {
  80. return Hive.box(hiveBoxName).put(
  81. supabasePersistSessionKey,
  82. persistSessionString,
  83. );
  84. }
  85. }