diff --git a/lib/src/anti-csrf.dart b/lib/src/anti-csrf.dart index d0a54ba..479c493 100644 --- a/lib/src/anti-csrf.dart +++ b/lib/src/anti-csrf.dart @@ -1,4 +1,5 @@ import 'package:shared_preferences/shared_preferences.dart'; +import 'package:supertokens_flutter/src/logger.dart'; class _AntiCSRFInfo { String? antiCSRF; @@ -15,6 +16,8 @@ class AntiCSRF { static String _sharedPreferencesKey = "supertokens-flutter-anti-csrf"; static Future getToken(String? associatedAccessTokenUpdate) async { + logDebugMessage('Getting token...') + logDebugMessage('associatedAccessTokenUpdate: ${associatedAccessTokenUpdate}') if (associatedAccessTokenUpdate == null) { AntiCSRF._antiCSRFInfo = null; return null; @@ -43,6 +46,8 @@ class AntiCSRF { static Future setToken( String antiCSRFToken, String? associatedAccessTokenUpdate) async { + logDebugMessage('Setting token...') + logDebugMessage('associatedAccessTokenUpdate: ${associatedAccessTokenUpdate}') if (associatedAccessTokenUpdate == null) { AntiCSRF._antiCSRFInfo = null; return; @@ -58,6 +63,7 @@ class AntiCSRF { } static Future removeToken() async { + logDebugMessage('Removing token...') SharedPreferences preferences = await SharedPreferences.getInstance(); await preferences.remove(AntiCSRF._sharedPreferencesKey); await preferences.reload(); diff --git a/lib/src/cookie-store.dart b/lib/src/cookie-store.dart index 2ab6837..c422cae 100644 --- a/lib/src/cookie-store.dart +++ b/lib/src/cookie-store.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:supertokens_flutter/src/logger.dart'; class SuperTokensCookieStore { static Map>? _allCookies; @@ -24,10 +25,12 @@ class SuperTokensCookieStore { /// Loads all cookies stored in shared preferences into the in memory map [_allCookies] static Future _loadFromPersistence() async { + logDebugMessage('Trying to load cookies from memory') _allCookies = {}; String cookiesStringInStorage = _sharedPreferences?.getString(_cookieSharedPrefsKey) ?? "{}"; Map cookiesInStorage = jsonDecode(cookiesStringInStorage); + logDebugMessage('cookies found: ${jsonEncode(cookiesInStorage)}') cookiesInStorage.forEach((key, value) { Uri uri = Uri.parse(key); List cookieStrings = List.from(value); @@ -49,6 +52,8 @@ class SuperTokensCookieStore { /// /// If you are trying to store cookies from a "set-cookie" header response, consider using the [saveFromSetCookieHeader] utility method which parses the header string. Future saveFromResponse(Uri uri, List cookies) async { + logDebugMessage('Saving cookies against: ${uri}') + logDebugMessage('Passed cookies: ${jsonEncode(cookies)}') await Future.forEach(cookies, (element) async { Uri uriToStore = await _getCookieUri(uri, element); List currentCookies = _allCookies?[uriToStore] ?? List.from([]); @@ -76,6 +81,7 @@ class SuperTokensCookieStore { /// Returns a Uri to use when saving the cookie Future _getCookieUri(Uri requestUri, Cookie cookie) async { + logDebugMessage('Creating cookie uri from: ${requestUri}') Uri cookieUri = Uri.parse( // ignore: unnecessary_null_comparison "${requestUri.scheme == null ? "http" : requestUri.scheme}://${requestUri.host}${cookie.path == null ? "" : cookie.path}"); @@ -98,6 +104,7 @@ class SuperTokensCookieStore { } } + logDebugMessage('Generated cookie uri: ${cookieUri}') return cookieUri; } @@ -105,6 +112,7 @@ class SuperTokensCookieStore { /// /// Strips expired cookies before storing in shared preferences Future _updatePersistentStorage() async { + logDebugMessage('Updating persistent storage with cookies...') Map> mapToStore = {}; _allCookies?.forEach((key, value) { String uriString = key.toString(); @@ -123,10 +131,12 @@ class SuperTokensCookieStore { /// /// If you are trying to add cookies to a "cookie" header for a network call, consider using the [getCookieHeaderStringForRequest] which creates a semi-colon separated cookie string for a given Uri. Future> getForRequest(Uri uri) async { + logDebugMessage('Getting cookies for request from uri: ${uri}') List cookiesToReturn = []; List allValidCookies = []; if (_allCookies == null) { + logDebugMessage('No cookies found') return cookiesToReturn; } @@ -155,6 +165,7 @@ class SuperTokensCookieStore { } } + logDebugMessage('Total cookies found ${cookiesToReturn.length}') return cookiesToReturn; } @@ -175,6 +186,7 @@ class SuperTokensCookieStore { /// Removes a list of cookies from persistent storage Future _removeFromPersistence( Uri uri, List cookiesToRemove) async { + logDebugMessage('Removing cookies from persistent storage...') List _cookiesToRemove = List.from(cookiesToRemove); List currentCookies = _allCookies?[uri] ?? List.from([]); @@ -192,6 +204,7 @@ class SuperTokensCookieStore { /// /// Does not return expired cookies and will remove them from persistent storage if any are found. Future getCookieHeaderStringForRequest(Uri uri) async { + logDebugMessage('Getting cookie header for request from uri: ${uri}') List cookies = await getForRequest(uri); // ignore: unnecessary_null_comparison if (cookies != null && cookies.isNotEmpty) { @@ -214,6 +227,7 @@ class SuperTokensCookieStore { /// /// Expired cookies are not saved. Future saveFromSetCookieHeader(Uri uri, String? setCookieHeader) async { + logDebugMessage('Saving cookie from header against uri: ${uri}') if (setCookieHeader != null) { await saveFromResponse(uri, getCookieListFromHeader(setCookieHeader)); } @@ -224,6 +238,7 @@ class SuperTokensCookieStore { setCookieHeader.split(RegExp(r',(?=[^ ])')); List setCookiesList = setCookiesStringList.map((e) => Cookie.fromSetCookieValue(e)).toList(); + logDebugMessage('Total cookies found in header: ${setCookiesList.length}') return setCookiesList; } } diff --git a/lib/src/dio-interceptor-wrapper.dart b/lib/src/dio-interceptor-wrapper.dart index 966e6ef..dd79d09 100644 --- a/lib/src/dio-interceptor-wrapper.dart +++ b/lib/src/dio-interceptor-wrapper.dart @@ -10,6 +10,7 @@ import 'package:supertokens_flutter/src/front-token.dart'; import 'package:supertokens_flutter/src/supertokens-http-client.dart'; import 'package:supertokens_flutter/src/supertokens.dart'; import 'package:supertokens_flutter/src/utilities.dart'; +import 'package:supertokens_flutter/src/logger.dart'; class SuperTokensInterceptorWrapper extends Interceptor { ReadWriteMutex _refreshAPILock = ReadWriteMutex(); @@ -22,6 +23,7 @@ class SuperTokensInterceptorWrapper extends Interceptor { @override void onRequest( RequestOptions options, RequestInterceptorHandler handler) async { + logDebugMessage('Intercepting request call') if (!SuperTokens.isInitCalled) { handler.reject(DioException( requestOptions: options, @@ -33,10 +35,13 @@ class SuperTokensInterceptorWrapper extends Interceptor { } if (!shouldRunDioInterceptor(options)) { + logDebugMessage('Skipping dio interceptor') return super.onRequest(options, handler); } + logDebugMessage('Running dio interceptor') if (Client.cookieStore == null) { + logDebugMessage('Initializing cookie store') Client.cookieStore = SuperTokensCookieStore(); } @@ -70,6 +75,7 @@ class SuperTokensInterceptorWrapper extends Interceptor { // If the request already has a "cookie" header, combine it with persistent cookies if (existingCookieHeader != null) { + logDebugMessage('Combining cookie header values') options.headers[HttpHeaders.cookieHeader] = "$existingCookieHeader;${newCookiesToAdd ?? ""}"; } else { @@ -90,9 +96,13 @@ class SuperTokensInterceptorWrapper extends Interceptor { @override void onResponse(Response response, ResponseInterceptorHandler handler) async { + logDebugMessage('Intercepting response call') if (!shouldRunDioInterceptor(response.requestOptions)) { + logDebugMessage('Skipping dio interceptor') return handler.next(response); } + + logDebugMessage('Running dio interceptor') _refreshAPILock.acquireWrite(); await saveTokensFromHeaders(response); String? frontTokenFromResponse = @@ -122,6 +132,7 @@ class SuperTokensInterceptorWrapper extends Interceptor { requestOptions.extra["__supertokensSessionRefreshAttempts"] ?? 0; if (sessionRefreshAttempts >= SuperTokens.config.maxRetryAttemptsForSessionRefresh) { + logDebugMessage('Max attempts of ${SuperTokens.config.maxRetryAttemptsForSessionRefresh} reached for refreshing, cannot continue') handler.reject( DioException( requestOptions: response.requestOptions, @@ -139,6 +150,7 @@ class SuperTokensInterceptorWrapper extends Interceptor { UnauthorisedResponse shouldRetry = await Client.onUnauthorisedResponse(_preRequestLocalSessionState); if (shouldRetry.status == UnauthorisedStatus.RETRY) { + logDebugMessage('Refreshing attempt: ${sessionRefreshAttempts + 1}') requestOptions.headers[HttpHeaders.cookieHeader] = userSetCookie; requestOptions.extra["__supertokensSessionRefreshAttempts"] = diff --git a/lib/src/supertokens.dart b/lib/src/supertokens.dart index f12993a..d9b7cde 100644 --- a/lib/src/supertokens.dart +++ b/lib/src/supertokens.dart @@ -93,6 +93,7 @@ class SuperTokens { static Future doesSessionExist() async { Map? tokenInfo = await FrontToken.getToken(); + logDebugMessage('Got token info: ${jsonEncode(tokenInfo)}') if (tokenInfo == null) { return false; } @@ -120,6 +121,7 @@ class SuperTokens { } static Future signOut({Function(Exception?)? completionHandler}) async { + logDebugMessage('Signing out user...') if (!(await doesSessionExist())) { SuperTokens.config.eventHandler(Eventype.SIGN_OUT); if (completionHandler != null) { @@ -139,6 +141,7 @@ class SuperTokens { return; } + logDebugMessage('Using signOutUrl: ${uri}') http.Request signOut = http.Request('post', uri); signOut = SuperTokens.config.preAPIHook(APIAction.SIGN_OUT, signOut); @@ -174,6 +177,7 @@ class SuperTokens { } static Future attemptRefreshingSession() async { + logDebugMessage('Attempting to refresh session...') LocalSessionState preRequestLocalSessionState = await SuperTokensUtils.getLocalSessionState(); bool shouldRetry = false;