From 0b6930b4a64374e5a400cb3b9a53c6c72c6fabcd Mon Sep 17 00:00:00 2001 From: dshukertjr <18113850+dshukertjr@users.noreply.github.com> Date: Wed, 22 Nov 2023 22:54:43 +0900 Subject: [PATCH] fix!(gotrue): only load the session from local storage on Supabase.init and lazy refresh the session later --- packages/gotrue/lib/src/gotrue_client.dart | 13 +++++++++- .../supabase_flutter/lib/src/supabase.dart | 4 +-- .../lib/src/supabase_auth.dart | 25 +++++++++++++++---- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/packages/gotrue/lib/src/gotrue_client.dart b/packages/gotrue/lib/src/gotrue_client.dart index 654acfc5..ab149a53 100644 --- a/packages/gotrue/lib/src/gotrue_client.dart +++ b/packages/gotrue/lib/src/gotrue_client.dart @@ -780,6 +780,17 @@ class GoTrueClient { ); } + /// Set the initially obtained session from local storage. + void setInitialSession(String jsonStr) { + final session = Session.fromJson(json.decode(jsonStr)); + if (session == null) { + throw notifyException(AuthException('Initial session is missing data.')); + } + + _currentSession = session; + notifyAllSubscribers(AuthChangeEvent.initialSession); + } + /// Recover session from stringified [Session]. Future recoverSession(String jsonStr) async { final session = Session.fromJson(json.decode(jsonStr)); @@ -801,7 +812,7 @@ class GoTrueClient { _currentSession?.user.id != session.user.id; _saveSession(session); - if (shouldEmitEvent) notifyAllSubscribers(AuthChangeEvent.signedIn); + if (shouldEmitEvent) notifyAllSubscribers(AuthChangeEvent.tokenRefreshed); return AuthResponse(session: session); } diff --git a/packages/supabase_flutter/lib/src/supabase.dart b/packages/supabase_flutter/lib/src/supabase.dart index b5176b3a..45dc4158 100644 --- a/packages/supabase_flutter/lib/src/supabase.dart +++ b/packages/supabase_flutter/lib/src/supabase.dart @@ -71,8 +71,7 @@ class Supabase { RealtimeClientOptions realtimeClientOptions = const RealtimeClientOptions(), PostgrestClientOptions postgrestOptions = const PostgrestClientOptions(), StorageClientOptions storageOptions = const StorageClientOptions(), - FlutterAuthClientOptions authOptions = - const FlutterAuthClientOptions(), + FlutterAuthClientOptions authOptions = const FlutterAuthClientOptions(), bool? debug, }) async { assert( @@ -107,6 +106,7 @@ class Supabase { _instance._supabaseAuth = SupabaseAuth(); await _instance._supabaseAuth.initialize(options: authOptions); + _instance._supabaseAuth.recoverSession(); return _instance; } diff --git a/packages/supabase_flutter/lib/src/supabase_auth.dart b/packages/supabase_flutter/lib/src/supabase_auth.dart index 884e31ee..a9903f90 100644 --- a/packages/supabase_flutter/lib/src/supabase_auth.dart +++ b/packages/supabase_flutter/lib/src/supabase_auth.dart @@ -47,15 +47,13 @@ class SupabaseAuth with WidgetsBindingObserver { final hasPersistedSession = await _localStorage.hasAccessToken(); var shouldEmitInitialSession = true; + if (hasPersistedSession) { final persistedSession = await _localStorage.accessToken(); + if (persistedSession != null) { try { - // At this point either an [AuthChangeEvent.signedIn] event or an exception should next be emitted by `onAuthStateChange` - shouldEmitInitialSession = false; - await Supabase.instance.client.auth.recoverSession(persistedSession); - } on AuthException catch (error, stackTrace) { - Supabase.instance.log(error.message, stackTrace); + Supabase.instance.client.auth.setInitialSession(persistedSession); } catch (error, stackTrace) { Supabase.instance.log(error.toString(), stackTrace); } @@ -79,6 +77,23 @@ class SupabaseAuth with WidgetsBindingObserver { } } + /// Recovers the session from local storage. + Future recoverSession() async { + try { + final hasPersistedSession = await _localStorage.hasAccessToken(); + if (hasPersistedSession) { + final persistedSession = await _localStorage.accessToken(); + if (persistedSession != null) { + await Supabase.instance.client.auth.recoverSession(persistedSession); + } + } + } on AuthException catch (error, stackTrace) { + Supabase.instance.log(error.message, stackTrace); + } catch (error, stackTrace) { + Supabase.instance.log(error.toString(), stackTrace); + } + } + /// Dispose the instance to free up resources void dispose() { if (!kIsWeb && Platform.environment.containsKey('FLUTTER_TEST')) {