Skip to content

Commit a40eff1

Browse files
Merge pull request #64 from supertokens/feat/add-support-for-debug-logging
feat: add support for debug logging
2 parents e6684c3 + 2686977 commit a40eff1

15 files changed

+268
-7
lines changed

.github/workflows/pre-commit-hook-run.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ jobs:
1212
pr-title:
1313
name: Pre commit hook check
1414
runs-on: ubuntu-latest
15-
container: rishabhpoddar/supertokens_flutter_sdk_testing
1615
steps:
1716
- uses: actions/checkout@v2
17+
- name: Make a dummy change to README.md
18+
run: |
19+
echo "# Dummy change for PR check" >> README.md
1820
- run: git init && git add --all && git -c user.name='test' -c user.email='test@example.com' commit -m 'init for pr action'
1921
- run: ./hooks/pre-commit.sh

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
## [0.6.2] - 2024-09-27
10+
11+
- Adds support for debug logs using a `debug` option in the init() method of the SDK.
12+
913
## [0.6.1] - 2024-07-12
1014

1115
### Changes

lib/src/anti-csrf.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:shared_preferences/shared_preferences.dart';
2+
import 'package:supertokens_flutter/src/logger.dart';
23

34
class _AntiCSRFInfo {
45
String? antiCSRF;
@@ -15,12 +16,16 @@ class AntiCSRF {
1516
static String _sharedPreferencesKey = "supertokens-flutter-anti-csrf";
1617

1718
static Future<String?> getToken(String? associatedAccessTokenUpdate) async {
19+
logDebugMessage('AntiCSRF.getToken: Getting token');
20+
logDebugMessage('AntiCSRF.getToken: associatedAccessTokenUpdate: ${associatedAccessTokenUpdate}');
1821
if (associatedAccessTokenUpdate == null) {
22+
logDebugMessage('AntiCSRF.getToken: associated token is null');
1923
AntiCSRF._antiCSRFInfo = null;
2024
return null;
2125
}
2226

2327
if (AntiCSRF._antiCSRFInfo == null) {
28+
logDebugMessage('AntiCSRF.getToken: antiCSRFInfo is null');
2429
SharedPreferences preferences = await SharedPreferences.getInstance();
2530
String? antiCSRFToken =
2631
preferences.getString(AntiCSRF._sharedPreferencesKey);
@@ -34,6 +39,7 @@ class AntiCSRF {
3439
} else if (AntiCSRF._antiCSRFInfo?.associatedAccessTokenUpdate != null &&
3540
AntiCSRF._antiCSRFInfo?.associatedAccessTokenUpdate !=
3641
associatedAccessTokenUpdate) {
42+
logDebugMessage('AntiCSRF.getToken: associatedAccessTokenUpdate did not match');
3743
AntiCSRF._antiCSRFInfo = null;
3844
return await AntiCSRF.getToken(associatedAccessTokenUpdate);
3945
}
@@ -43,24 +49,32 @@ class AntiCSRF {
4349

4450
static Future<void> setToken(
4551
String antiCSRFToken, String? associatedAccessTokenUpdate) async {
52+
logDebugMessage('AntiCSRF.setToken: Setting token');
53+
logDebugMessage('AntiCSRF.setToken: associatedAccessTokenUpdate: ${associatedAccessTokenUpdate}');
4654
if (associatedAccessTokenUpdate == null) {
55+
logDebugMessage('AntiCSRF.setToken: associated token is null');
4756
AntiCSRF._antiCSRFInfo = null;
4857
return;
4958
}
5059

5160
SharedPreferences preferences = await SharedPreferences.getInstance();
61+
logDebugMessage('AntiCSRF.setToken: setting preferences for: ${AntiCSRF._sharedPreferencesKey}');
5262
await preferences.setString(AntiCSRF._sharedPreferencesKey, antiCSRFToken);
5363
await preferences.reload();
5464

65+
logDebugMessage('AntiCSRF.setToken: storing the token before returning');
5566
AntiCSRF._antiCSRFInfo = _AntiCSRFInfo(
5667
antiCSRFToken: antiCSRFToken,
5768
associatedAccessTokenUpdate: associatedAccessTokenUpdate);
5869
}
5970

6071
static Future<void> removeToken() async {
72+
logDebugMessage('AntiCSRF.removeToken: Removing token');
73+
logDebugMessage('AntiCSRF.removeToken: Updating preferences');
6174
SharedPreferences preferences = await SharedPreferences.getInstance();
6275
await preferences.remove(AntiCSRF._sharedPreferencesKey);
6376
await preferences.reload();
77+
logDebugMessage('AntiCSRF.removeToken: Setting token to null');
6478
AntiCSRF._antiCSRFInfo = null;
6579
}
6680
}

lib/src/cookie-store.dart

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'dart:convert';
33
import 'dart:io';
44

55
import 'package:shared_preferences/shared_preferences.dart';
6+
import 'package:supertokens_flutter/src/logger.dart';
67

78
class SuperTokensCookieStore {
89
static Map<Uri, List<Cookie>>? _allCookies;
@@ -24,10 +25,12 @@ class SuperTokensCookieStore {
2425

2526
/// Loads all cookies stored in shared preferences into the in memory map [_allCookies]
2627
static Future<void> _loadFromPersistence() async {
28+
logDebugMessage('SuperTokensCookieStore._loadFromPersistence: Trying to load cookies from memory');
2729
_allCookies = {};
2830
String cookiesStringInStorage =
2931
_sharedPreferences?.getString(_cookieSharedPrefsKey) ?? "{}";
3032
Map<String, dynamic> cookiesInStorage = jsonDecode(cookiesStringInStorage);
33+
logDebugMessage('SuperTokensCookieStore._loadFromPersistence: cookies found: ${jsonEncode(cookiesInStorage)}');
3134
cookiesInStorage.forEach((key, value) {
3235
Uri uri = Uri.parse(key);
3336
List<String> cookieStrings = List.from(value);
@@ -49,8 +52,11 @@ class SuperTokensCookieStore {
4952
///
5053
/// If you are trying to store cookies from a "set-cookie" header response, consider using the [saveFromSetCookieHeader] utility method which parses the header string.
5154
Future<void> saveFromResponse(Uri uri, List<Cookie> cookies) async {
55+
logDebugMessage('SuperTokensCookieStore.saveFromResponse: Saving cookies against: ${uri}');
56+
logDebugMessage('SuperTokensCookieStore.saveFromResponse: Passed cookies: ${jsonEncode(cookies)}');
5257
await Future.forEach<Cookie>(cookies, (element) async {
5358
Uri uriToStore = await _getCookieUri(uri, element);
59+
logDebugMessage('SuperTokensCookieStore.saveFromResponse: Setting based on uriToStore: ${uriToStore}');
5460
List<Cookie> currentCookies = _allCookies?[uriToStore] ?? List.from([]);
5561
currentCookies = currentCookies
5662
// ignore: unnecessary_null_comparison
@@ -68,6 +74,7 @@ class SuperTokensCookieStore {
6874
_allCookies?[uriToStore] = currentCookies;
6975
});
7076

77+
logDebugMessage('SuperTokensCookieStore.saveFromResponse: Removing empty cookies');
7178
_allCookies?.removeWhere((key, value) => value.isEmpty);
7279

7380
await _updatePersistentStorage();
@@ -76,14 +83,17 @@ class SuperTokensCookieStore {
7683

7784
/// Returns a Uri to use when saving the cookie
7885
Future<Uri> _getCookieUri(Uri requestUri, Cookie cookie) async {
86+
logDebugMessage('SuperTokensCookieStore._getCookieUri: Creating cookie uri from: ${requestUri}');
7987
Uri cookieUri = Uri.parse(
8088
// ignore: unnecessary_null_comparison
8189
"${requestUri.scheme == null ? "http" : requestUri.scheme}://${requestUri.host}${cookie.path == null ? "" : cookie.path}");
8290

8391
if (cookie.domain != null) {
8492
String domain = cookie.domain ?? "";
93+
logDebugMessage('SuperTokensCookiesStore._getCookieUri: got domain: ${domain}');
8594
if (domain[0] == ".") {
8695
domain = domain.substring(1);
96+
logDebugMessage('SuperTokensCookiesStore._getCookieUri: Using domain substring: ${domain}');
8797
}
8898

8999
try {
@@ -98,22 +108,27 @@ class SuperTokensCookieStore {
98108
}
99109
}
100110

111+
logDebugMessage('Generated cookie uri: ${cookieUri}');
101112
return cookieUri;
102113
}
103114

104115
/// Uses the [_allCookies] map to update values in shared preferences.
105116
///
106117
/// Strips expired cookies before storing in shared preferences
107118
Future<void> _updatePersistentStorage() async {
119+
logDebugMessage('SuperTokensCookieStore._updatePersistentStorage: Updating persistent storage with cookies');
108120
Map<String, List<String>> mapToStore = {};
109121
_allCookies?.forEach((key, value) {
110122
String uriString = key.toString();
111123
List<String> cookieStrings =
112124
List.from(value.map((e) => e.toString()).toList());
125+
logDebugMessage('SuperTokensCookieStore._updatePersistentStorage: Setting to ${uriString}');
126+
logDebugMessage('SuperTokensCookieStore._updatePersistentStorage: Setting value ${cookieStrings}');
113127
mapToStore[uriString] = cookieStrings;
114128
});
115129

116130
String stringToStore = jsonEncode(mapToStore);
131+
logDebugMessage('SuperTokensCookieStore._updatePersistentStorage: Storing preferences: ${stringToStore}');
117132
await _sharedPreferences?.setString(_cookieSharedPrefsKey, stringToStore);
118133
}
119134

@@ -123,10 +138,12 @@ class SuperTokensCookieStore {
123138
///
124139
/// 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.
125140
Future<List<Cookie>> getForRequest(Uri uri) async {
141+
logDebugMessage('SuperTokensCookieStore.getForRequest: Getting cookies for request from uri: ${uri}');
126142
List<Cookie> cookiesToReturn = [];
127143
List<Cookie> allValidCookies = [];
128144

129145
if (_allCookies == null) {
146+
logDebugMessage('SuperTokensCookieStore.getForRequest: No cookies found');
130147
return cookiesToReturn;
131148
}
132149

@@ -137,6 +154,7 @@ class SuperTokensCookieStore {
137154
allValidCookies.addAll(storedCookies);
138155
}
139156
}
157+
logDebugMessage('SuperTokensCookieStore.getForRequest: Valid cookies found: ${allValidCookies.length}');
140158

141159
if (allValidCookies.isNotEmpty) {
142160
List<Cookie> cookiesToRemoveFromStorage = [];
@@ -150,21 +168,29 @@ class SuperTokensCookieStore {
150168
}
151169
});
152170

171+
logDebugMessage('SuperTokensCookieStore.getForRequest: Total cookies to remove: ${cookiesToRemoveFromStorage.length}');
153172
if (cookiesToRemoveFromStorage.isNotEmpty) {
154173
await _removeFromPersistence(uri, cookiesToRemoveFromStorage);
155174
}
156175
}
157176

177+
logDebugMessage('SuperTokensCookieStore.getForRequest: Total cookies found ${cookiesToReturn.length}');
158178
return cookiesToReturn;
159179
}
160180

161181
/// Checks whether a network request's domain can be considered valid for a cookie to be sent
162182
bool _doesDomainMatch(String cookieHost, String requestHost) {
183+
logDebugMessage('SuperTokensCookieStore._doesDomainMatch: Determining if domain matches');
184+
logDebugMessage('SuperTokensCookieStore._doesDomainMatch: cookiesHost: ${cookieHost}');
185+
logDebugMessage('SuperTokensCookieStore._doesDomainMatch: requestHost: ${requestHost}');
163186
return requestHost == cookieHost || requestHost.endsWith(".$cookieHost");
164187
}
165188

166189
/// Checks whether a network request's path can be considered valid for a cookie to be sent
167190
bool _doesPathMatch(String cookiePath, String requestPath) {
191+
logDebugMessage('SuperTokensCookieStore._doesPathMatch: Determining if path matches');
192+
logDebugMessage('SuperTokensCookieStore._doesPathMatch: cookiePath: ${cookiePath}');
193+
logDebugMessage('SuperTokensCookieStore._doesPathMatch: requestPath: ${requestPath}');
168194
return (requestPath == cookiePath) ||
169195
(requestPath.startsWith(cookiePath) &&
170196
cookiePath[cookiePath.length - 1] == "/") ||
@@ -175,9 +201,13 @@ class SuperTokensCookieStore {
175201
/// Removes a list of cookies from persistent storage
176202
Future<void> _removeFromPersistence(
177203
Uri uri, List<Cookie> cookiesToRemove) async {
204+
logDebugMessage('SuperTokensCookieStore._removeFromPersistence: Removing cookies from persistent storage');
205+
logDebugMessage('SuperTokensCookieStore._removeFromPersistence: Total cookies to remove: ${cookiesToRemove.length}');
206+
logDebugMessage('SuperTokensCookieStore._removeFromPersistence: uri: ${uri}');
178207
List<Cookie> _cookiesToRemove = List.from(cookiesToRemove);
179208
List<Cookie> currentCookies = _allCookies?[uri] ?? List.from([]);
180209

210+
logDebugMessage('SuperTokensCookieStore._removeFromPersistence: Removing each cookie');
181211
_cookiesToRemove.forEach((element) {
182212
currentCookies.remove(element);
183213
});
@@ -192,7 +222,9 @@ class SuperTokensCookieStore {
192222
///
193223
/// Does not return expired cookies and will remove them from persistent storage if any are found.
194224
Future<String> getCookieHeaderStringForRequest(Uri uri) async {
225+
logDebugMessage('SuperTokensCookieStore.getCookieHeaderStringForRequest: Getting cookie header for request from uri: ${uri}');
195226
List<Cookie> cookies = await getForRequest(uri);
227+
logDebugMessage('SuperTokensCookieStore.getCookieHeaderStringForRequest: Total cookies found: ${cookies.length}');
196228
// ignore: unnecessary_null_comparison
197229
if (cookies != null && cookies.isNotEmpty) {
198230
List<String> cookiesStringList =
@@ -201,6 +233,7 @@ class SuperTokensCookieStore {
201233
return cookieHeaderString;
202234
}
203235

236+
logDebugMessage('SuperTokensCookieStore.getCookieHeaderStringForRequest: Returning empty value');
204237
return "";
205238
}
206239

@@ -214,16 +247,19 @@ class SuperTokensCookieStore {
214247
///
215248
/// Expired cookies are not saved.
216249
Future<void> saveFromSetCookieHeader(Uri uri, String? setCookieHeader) async {
250+
logDebugMessage('SuperTokensCookieStore.saveFromSetCookieHeader: Saving cookie from header against uri: ${uri}');
217251
if (setCookieHeader != null) {
218252
await saveFromResponse(uri, getCookieListFromHeader(setCookieHeader));
219253
}
220254
}
221255

222256
static List<Cookie> getCookieListFromHeader(String setCookieHeader) {
257+
logDebugMessage('SuperTokensCookieStore.getCookieListFromHeader: Getting cookie list from header: ${setCookieHeader}');
223258
List<String> setCookiesStringList =
224259
setCookieHeader.split(RegExp(r',(?=[^ ])'));
225260
List<Cookie> setCookiesList =
226261
setCookiesStringList.map((e) => Cookie.fromSetCookieValue(e)).toList();
262+
logDebugMessage('SuperTokensCookieStore.getCookieListFromHeader: Total cookies found in header: ${setCookiesList.length}');
227263
return setCookiesList;
228264
}
229265
}

0 commit comments

Comments
 (0)