@@ -14,9 +14,11 @@ import 'package:jwt_decode/jwt_decode.dart';
1414import 'package:meta/meta.dart' ;
1515import 'package:retry/retry.dart' ;
1616import 'package:rxdart/subjects.dart' ;
17+ import 'package:logging/logging.dart' ;
1718
1819import 'broadcast_stub.dart' if (dart.library.html) './broadcast_web.dart'
1920 as web;
21+ import 'version.dart' ;
2022
2123part 'gotrue_mfa_api.dart' ;
2224
@@ -87,6 +89,8 @@ class GoTrueClient {
8789
8890 final AuthFlowType _flowType;
8991
92+ final _log = Logger ('supabase.gotrue' );
93+
9094 /// Proxy to the web BroadcastChannel API. Should be null on non-web platforms.
9195 BroadcastChannel ? _broadcastChannel;
9296
@@ -101,20 +105,22 @@ class GoTrueClient {
101105 GotrueAsyncStorage ? asyncStorage,
102106 AuthFlowType flowType = AuthFlowType .pkce,
103107 }) : _url = url ?? Constants .defaultGotrueUrl,
104- _headers = headers ?? {},
108+ _headers = {
109+ ...Constants .defaultHeaders,
110+ ...? headers,
111+ },
105112 _httpClient = httpClient,
106113 _asyncStorage = asyncStorage,
107114 _flowType = flowType {
108115 _autoRefreshToken = autoRefreshToken ?? true ;
109116
110117 final gotrueUrl = url ?? Constants .defaultGotrueUrl;
111- final gotrueHeader = {
112- ...Constants .defaultHeaders,
113- if (headers != null ) ...headers,
114- };
118+ _log.config (
119+ 'Initialize GoTrueClient v$version with url: $_url , autoRefreshToken: $_autoRefreshToken , flowType: $_flowType , tickDuration: ${Constants .autoRefreshTickDuration }, tickThreshold: ${Constants .autoRefreshTickThreshold }' );
120+ _log.finest ('Initialize with headers: $_headers ' );
115121 admin = GoTrueAdminApi (
116122 gotrueUrl,
117- headers: gotrueHeader ,
123+ headers: _headers ,
118124 httpClient: httpClient,
119125 );
120126 mfa = GoTrueMFAApi (
@@ -617,8 +623,10 @@ class GoTrueClient {
617623 /// If the current session's refresh token is invalid, an error will be thrown.
618624 Future <AuthResponse > refreshSession ([String ? refreshToken]) async {
619625 if (currentSession? .accessToken == null ) {
626+ _log.warning ("Can't refresh session, no current session found." );
620627 throw AuthSessionMissingException ();
621628 }
629+ _log.info ('Refresh session' );
622630
623631 final currentSessionRefreshToken =
624632 refreshToken ?? _currentSession? .refreshToken;
@@ -842,6 +850,7 @@ class GoTrueClient {
842850 Future <void > signOut ({
843851 SignOutScope scope = SignOutScope .local,
844852 }) async {
853+ _log.info ('Signing out user with scope: $scope ' );
845854 final accessToken = currentSession? .accessToken;
846855
847856 if (scope != SignOutScope .others) {
@@ -966,13 +975,15 @@ class GoTrueClient {
966975 try {
967976 final session = Session .fromJson (json.decode (jsonStr));
968977 if (session == null ) {
978+ _log.warning ("Can't recover session from string, session is null" );
969979 await signOut ();
970980 throw notifyException (
971981 AuthException ('Current session is missing data.' ),
972982 );
973983 }
974984
975985 if (session.isExpired) {
986+ _log.fine ('Session from recovery is expired' );
976987 final refreshToken = session.refreshToken;
977988 if (_autoRefreshToken && refreshToken != null ) {
978989 return await _callRefreshToken (refreshToken);
@@ -1002,6 +1013,7 @@ class GoTrueClient {
10021013 void startAutoRefresh () async {
10031014 stopAutoRefresh ();
10041015
1016+ _log.fine ('Starting auto refresh' );
10051017 _autoRefreshTicker = Timer .periodic (
10061018 Constants .autoRefreshTickDuration,
10071019 (Timer t) => _autoRefreshTokenTick (),
@@ -1013,6 +1025,7 @@ class GoTrueClient {
10131025
10141026 /// Stops an active auto refresh process running in the background (if any).
10151027 void stopAutoRefresh () {
1028+ _log.fine ('Stopping auto refresh' );
10161029 _autoRefreshTicker? .cancel ();
10171030 _autoRefreshTicker = null ;
10181031 }
@@ -1037,12 +1050,15 @@ class GoTrueClient {
10371050 Constants .autoRefreshTickDuration.inMilliseconds)
10381051 .floor ();
10391052
1053+ _log.finer ('Access token expires in $expiresInTicks ticks' );
1054+
10401055 // Only tick if the next tick comes after the retry threshold
10411056 if (expiresInTicks <= Constants .autoRefreshTickThreshold) {
10421057 await _callRefreshToken (refreshToken);
10431058 }
10441059 } catch (error) {
1045- // Do nothing. JS client prints here
1060+ // Do nothing. JS client prints here, but error is already tracked via
1061+ // [notifyException]
10461062 }
10471063 }
10481064
@@ -1055,6 +1071,7 @@ class GoTrueClient {
10551071 // Make a GET request
10561072 () async {
10571073 attempt++ ;
1074+ _log.fine ('Attempt $attempt to refresh token' );
10581075 final options = GotrueRequestOptions (
10591076 headers: _headers,
10601077 body: {'refresh_token' : refreshToken},
@@ -1129,11 +1146,14 @@ class GoTrueClient {
11291146
11301147 /// set currentSession and currentUser
11311148 void _saveSession (Session session) {
1149+ _log.finest ('Saving session: $session ' );
1150+ _log.fine ('Saving session' );
11321151 _currentSession = session;
11331152 _currentUser = session.user;
11341153 }
11351154
11361155 void _removeSession () {
1156+ _log.fine ('Removing session' );
11371157 _currentSession = null ;
11381158 _currentUser = null ;
11391159 }
@@ -1151,6 +1171,8 @@ class GoTrueClient {
11511171 _broadcastChannelSubscription =
11521172 _broadcastChannel? .onMessage.listen ((messageEvent) {
11531173 final rawEvent = messageEvent['event' ];
1174+ _log.finest ('Received broadcast message: $messageEvent ' );
1175+ _log.info ('Received broadcast event: $rawEvent ' );
11541176 final event = switch (rawEvent) {
11551177 // This library sends the js name of the event to be comptabile with
11561178 // the js library, so we need to convert it back to the dart name
@@ -1202,6 +1224,7 @@ class GoTrueClient {
12021224 Future <AuthResponse > _callRefreshToken (String refreshToken) async {
12031225 // Refreshing is already in progress
12041226 if (_refreshTokenCompleter != null ) {
1227+ _log.finer ("Don't call refresh token, already in progress" );
12051228 return _refreshTokenCompleter! .future;
12061229 }
12071230
@@ -1213,6 +1236,7 @@ class GoTrueClient {
12131236 (_) => null ,
12141237 onError: (_, __) => null ,
12151238 );
1239+ _log.fine ('Refresh access token' );
12161240
12171241 final data = await _refreshAccessToken (refreshToken);
12181242
@@ -1232,15 +1256,15 @@ class GoTrueClient {
12321256 _removeSession ();
12331257 notifyAllSubscribers (AuthChangeEvent .signedOut);
12341258 } else {
1235- _onAuthStateChangeController. addError (error, stack);
1259+ notifyException (error, stack);
12361260 }
12371261
12381262 _refreshTokenCompleter? .completeError (error);
12391263
12401264 rethrow ;
12411265 } catch (error, stack) {
12421266 _refreshTokenCompleter? .completeError (error);
1243- _onAuthStateChangeController. addError (error, stack);
1267+ notifyException (error, stack);
12441268 rethrow ;
12451269 } finally {
12461270 _refreshTokenCompleter = null ;
@@ -1265,13 +1289,15 @@ class GoTrueClient {
12651289 });
12661290 }
12671291 final state = AuthState (event, session, fromBroadcast: ! broadcast);
1292+ _log.finest ('onAuthStateChange: $state ' );
12681293 _onAuthStateChangeController.add (state);
12691294 _onAuthStateChangeControllerSync.add (state);
12701295 }
12711296
12721297 /// For internal use only.
12731298 @internal
12741299 Object notifyException (Object exception, [StackTrace ? stackTrace]) {
1300+ _log.warning ('Notifying exception' , exception, stackTrace);
12751301 _onAuthStateChangeController.addError (
12761302 exception,
12771303 stackTrace ?? StackTrace .current,
0 commit comments