Skip to content

Commit

Permalink
fix!(gotrue): only load the session from local storage on Supabase.in…
Browse files Browse the repository at this point in the history
…it and lazy refresh the session later
  • Loading branch information
dshukertjr committed Nov 22, 2023
1 parent 60a2515 commit 0b6930b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
13 changes: 12 additions & 1 deletion packages/gotrue/lib/src/gotrue_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<AuthResponse> recoverSession(String jsonStr) async {
final session = Session.fromJson(json.decode(jsonStr));
Expand All @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/supabase_flutter/lib/src/supabase.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -107,6 +106,7 @@ class Supabase {

_instance._supabaseAuth = SupabaseAuth();
await _instance._supabaseAuth.initialize(options: authOptions);
_instance._supabaseAuth.recoverSession();

return _instance;
}
Expand Down
25 changes: 20 additions & 5 deletions packages/supabase_flutter/lib/src/supabase_auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -79,6 +77,23 @@ class SupabaseAuth with WidgetsBindingObserver {
}
}

/// Recovers the session from local storage.
Future<void> 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')) {
Expand Down

0 comments on commit 0b6930b

Please sign in to comment.