diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cfcc12..2865ef0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.3.0] - 2023-11-13 + +- Added Dio extension for interceptor setup +- Updated the mutex package to version ^3.1.0 + +### Breaking Changes + +- Updated the dio package to version ^5.0.0 + ## [0.2.8] - 2023-09-13 - Adds 1.18 to the list of supported FDI versions diff --git a/README.md b/README.md index 3f5f7d5..067e3d4 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,17 @@ void setup() { } ``` +Or use instance method instead. + +```dart +import 'package:supertokens_flutter/dio.dart'; + +void setup() { + Dio dio = Dio(); // Create a Dio instance. + dio.addSupertokensInterceptor(); +} +``` + #### Making network requests ```dart diff --git a/lib/dio.dart b/lib/dio.dart index 1890346..452de70 100644 --- a/lib/dio.dart +++ b/lib/dio.dart @@ -1 +1,2 @@ export 'src/dio-interceptor-wrapper.dart' show SuperTokensInterceptorWrapper; +export 'src/supertokens_dio_extension.dart' show SuperTokensDioExtension; \ No newline at end of file diff --git a/lib/src/dio-interceptor-wrapper.dart b/lib/src/dio-interceptor-wrapper.dart index 7088892..13524fd 100644 --- a/lib/src/dio-interceptor-wrapper.dart +++ b/lib/src/dio-interceptor-wrapper.dart @@ -23,9 +23,9 @@ class SuperTokensInterceptorWrapper extends Interceptor { void onRequest( RequestOptions options, RequestInterceptorHandler handler) async { if (!SuperTokens.isInitCalled) { - handler.reject(DioError( + handler.reject(DioException( requestOptions: options, - type: DioErrorType.other, + type: DioExceptionType.unknown, error: SuperTokensException( "SuperTokens.init must be called before using Client"), )); @@ -52,7 +52,7 @@ class SuperTokensInterceptorWrapper extends Interceptor { } SuperTokensTokenTransferMethod tokenTransferMethod = - SuperTokens.config.tokenTransferMethod!; + SuperTokens.config.tokenTransferMethod; options.headers["st-auth-mode"] = tokenTransferMethod.getValue(); options = await _setAuthorizationHeaderIfRequired(options); @@ -131,10 +131,10 @@ class SuperTokensInterceptorWrapper extends Interceptor { } else { if (shouldRetry.exception != null) { handler.reject( - DioError( + DioException( requestOptions: response.requestOptions, error: SuperTokensException(shouldRetry.exception!.message), - type: DioErrorType.other), + type: DioExceptionType.unknown), ); return; } else { @@ -146,13 +146,13 @@ class SuperTokensInterceptorWrapper extends Interceptor { _refreshAPILock.release(); return handler.next(response); } - } on DioError catch (e) { + } on DioException catch (e) { handler.reject(e); } catch (e) { handler.reject( - DioError( + DioException( requestOptions: response.requestOptions, - type: DioErrorType.other, + type: DioExceptionType.unknown, error: e), ); } finally { diff --git a/lib/src/supertokens_dio_extension.dart b/lib/src/supertokens_dio_extension.dart new file mode 100644 index 0000000..313eb61 --- /dev/null +++ b/lib/src/supertokens_dio_extension.dart @@ -0,0 +1,20 @@ +import 'package:dio/dio.dart'; +import 'package:supertokens_flutter/src/dio-interceptor-wrapper.dart'; + +/// Dio extension for flexible Dio instance setup. +/// +/// Usage: +/// ```dart +/// import "package:supertokens_flutter/dio.dart"; +/// +/// final dio = Dio() +/// ..addSupertokensInterceptor() +/// ..addSentry() +/// // ... +/// ``` +extension SuperTokensDioExtension on Dio { + /// Adds the SuperTokens interceptor to the Dio instance. + void addSupertokensInterceptor() { + interceptors.add(SuperTokensInterceptorWrapper(client: this)); + } +} diff --git a/lib/src/version.dart b/lib/src/version.dart index 9875959..60b738f 100644 --- a/lib/src/version.dart +++ b/lib/src/version.dart @@ -1,4 +1,4 @@ class Version { static List supported_fdi = ["1.16", "1.17", "1.18"]; - static String sdkVersion = "0.2.8"; + static String sdkVersion = "0.3.0"; } diff --git a/lib/supertokens.dart b/lib/supertokens.dart index 32903b8..3b1f117 100644 --- a/lib/supertokens.dart +++ b/lib/supertokens.dart @@ -5,4 +5,4 @@ library supertokens; export "src/supertokens.dart"; -export "src/errors.dart"; +export "src/errors.dart"; \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 14742d8..6be09a5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -93,18 +93,18 @@ packages: dependency: "direct main" description: name: dio - sha256: "7d328c4d898a61efc3cd93655a0955858e29a0aa647f0f9e02d59b3bb275e2e8" + sha256: "417e2a6f9d83ab396ec38ff4ea5da6c254da71e4db765ad737a42af6930140b7" url: "https://pub.dev" source: hosted - version: "4.0.6" + version: "5.3.3" dio_http_formatter: dependency: "direct dev" description: name: dio_http_formatter - sha256: b2ce51f686e0b2739a10698cf8d518b0780f0e54fa3b23321782064694081259 + sha256: "3ac0f427cbe1ac9dfaf14231bf2cccdc49c9015e67b786bde6bd9bacd148218d" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "3.2.1" fake_async: dependency: transitive description: @@ -204,10 +204,10 @@ packages: dependency: transitive description: name: logger - sha256: "7ad7215c15420a102ec687bb320a7312afd449bac63bfb1c60d9787c27b9767f" + sha256: "6bbb9d6f7056729537a4309bda2e74e18e5d9f14302489cc1e93f33b3fe32cac" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "2.0.2+1" logging: dependency: transitive description: @@ -252,10 +252,10 @@ packages: dependency: "direct main" description: name: mutex - sha256: "03116a4e46282a671b46c12de649d72c0ed18188ffe12a8d0fc63e83f4ad88f4" + sha256: "8827da25de792088eb33e572115a5eb0d61d61a3c01acbc8bcbe76ed78f1a1f2" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.1.0" node_preamble: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 399f6d9..b7e1da6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: supertokens_flutter description: SuperTokens SDK for Flutter apps -version: 0.2.8 +version: 0.3.0 homepage: https://supertokens.com/ repository: https://github.com/supertokens/supertokens-flutter issue_tracker: https://github.com/supertokens/supertokens-flutter/issues @@ -18,18 +18,17 @@ dependencies: sdk: flutter http: "<1.2.0" shared_preferences: ">=2.0.0 <3.0.0" - mutex: ^3.0.0 - dio: ^4.0.0 + mutex: ^3.1.0 + dio: ^5.0.0 dev_dependencies: flutter_test: sdk: flutter test: ^1.21.4 - dio_http_formatter: ^2.1.0 + dio_http_formatter: ^3.2.1 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter. flutter: - diff --git a/test/accesstoken_dio_test.dart b/test/accesstoken_dio_test.dart index ee04fc9..e61733a 100644 --- a/test/accesstoken_dio_test.dart +++ b/test/accesstoken_dio_test.dart @@ -1,5 +1,4 @@ import 'package:dio/dio.dart'; -import 'package:dio_http_formatter/dio_http_formatter.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:supertokens_flutter/src/dio-interceptor-wrapper.dart'; @@ -28,8 +27,8 @@ void main() { Dio dio = Dio( BaseOptions( baseUrl: apiBasePath, - connectTimeout: 5000, - receiveTimeout: 500, + connectTimeout: Duration(seconds: 5), + receiveTimeout: Duration(milliseconds: 500), ), ); dio.interceptors.add(SuperTokensInterceptorWrapper(client: dio)); diff --git a/test/accesstoken_http_test.dart b/test/accesstoken_http_test.dart index 15ac522..b3930c6 100644 --- a/test/accesstoken_http_test.dart +++ b/test/accesstoken_http_test.dart @@ -1,12 +1,7 @@ -import 'dart:convert'; -import 'dart:ffi'; import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:supertokens_flutter/http.dart' as http; -import 'package:supertokens_flutter/src/anti-csrf.dart'; -import 'package:supertokens_flutter/src/front-token.dart'; -import 'package:supertokens_flutter/src/utilities.dart'; import 'package:supertokens_flutter/supertokens.dart'; import 'test-utils.dart'; diff --git a/test/concurrency_dio_tests.dart b/test/concurrency_dio_tests.dart index 1a7e3ad..06aea40 100644 --- a/test/concurrency_dio_tests.dart +++ b/test/concurrency_dio_tests.dart @@ -30,8 +30,8 @@ void main() { Dio dio = Dio( BaseOptions( baseUrl: apiBasePath, - connectTimeout: 5000, - receiveTimeout: 500, + connectTimeout: Duration(seconds: 5), + receiveTimeout: Duration(milliseconds: 500), ), ); dio.interceptors.add(SuperTokensInterceptorWrapper(client: dio)); diff --git a/test/dioInterceptor_test.dart b/test/dioInterceptor_test.dart index 94a2def..3159b62 100644 --- a/test/dioInterceptor_test.dart +++ b/test/dioInterceptor_test.dart @@ -29,8 +29,8 @@ void main() { Dio dio = Dio( BaseOptions( baseUrl: apiBasePath, - connectTimeout: 5000, - receiveTimeout: 500, + connectTimeout: Duration(seconds: 5), + receiveTimeout: Duration(milliseconds: 500), ), ); dio.interceptors.add(SuperTokensInterceptorWrapper(client: dio)); @@ -403,8 +403,8 @@ void main() { Dio dio = Dio( BaseOptions( baseUrl: apiBasePath, - connectTimeout: 5000, - receiveTimeout: 500, + connectTimeout: Duration(seconds: 5), + receiveTimeout: Duration(milliseconds: 500), ), ); dio.interceptors.add(SuperTokensInterceptorWrapper(client: dio)); @@ -421,8 +421,8 @@ void main() { Dio dio = Dio( BaseOptions( baseUrl: apiBasePath, - connectTimeout: 5000, - receiveTimeout: 500, + connectTimeout: Duration(seconds: 5), + receiveTimeout: Duration(milliseconds: 500), ), ); dio.interceptors.add(HttpFormatter()); diff --git a/test/dio_extension_interceptor_test.dart b/test/dio_extension_interceptor_test.dart new file mode 100644 index 0000000..b18feff --- /dev/null +++ b/test/dio_extension_interceptor_test.dart @@ -0,0 +1,405 @@ +import 'package:dio/dio.dart'; +import 'package:dio_http_formatter/dio_http_formatter.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:supertokens_flutter/src/supertokens.dart'; +import 'package:supertokens_flutter/src/utilities.dart'; +import 'package:supertokens_flutter/supertokens.dart'; +import 'package:supertokens_flutter/dio.dart'; + +import 'test-utils.dart'; + +void main() { + String apiBasePath = SuperTokensTestUtils.baseUrl; + + setUpAll(() async { + TestWidgetsFlutterBinding.ensureInitialized(); + await SuperTokensTestUtils.beforeAllTest(); + }); + + setUp(() async { + SharedPreferences.setMockInitialValues({}); + await SuperTokensTestUtils.beforeEachTest(); + SuperTokens.isInitCalled = false; + await Future.delayed(Duration(seconds: 1), () {}); + }); + + tearDownAll(() => SuperTokensTestUtils.afterAllTest()); + + Dio setUpDio() { + + final dio = Dio( + BaseOptions( + baseUrl: apiBasePath, + connectTimeout: Duration(seconds: 5), + receiveTimeout: Duration(milliseconds: 500), + ), + ) + ..addSupertokensInterceptor(); // Set up dio with cascade operator + + return dio; + } + + test("Test session expired without refresh call", () async { + await SuperTokensTestUtils.startST(validity: 3); + SuperTokens.init(apiDomain: apiBasePath); + Dio dio = setUpDio(); + var resp = await dio.get("/"); + if (resp.statusCode != 401) + fail("API should have returned unAuthorised but didn't"); + int counter = await SuperTokensTestUtils.refreshTokenCounter(); + if (counter != 0) fail("Refresh counter returned non zero value"); + }); + + test("Test custom headers for refresh API", () async { + await SuperTokensTestUtils.startST(validity: 3); + SuperTokens.init( + apiDomain: apiBasePath, + preAPIHook: (action, req) { + if (action == APIAction.REFRESH_TOKEN) + req.headers.addAll({"custom-header": "custom-value"}); + return req; + }, + ); + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio = setUpDio(); + var resp = await dio.fetch(req); + if (resp.statusCode != 200) + fail("Login req failed"); + else { + await Future.delayed(Duration(seconds: 10), () {}); + var userInfoResp = await dio.get("/"); + if (userInfoResp.statusCode != 200) {} + } + var refreshResponse = await dio.get("/refreshHeader"); + if (refreshResponse.statusCode != 200) fail("Refresh Request failed"); + var respJson = refreshResponse.data; + if (respJson["value"] != "custom-value") fail("Header not sent"); + }); + + test("Test to check if request can be made without Supertokens.init", + () async { + await SuperTokensTestUtils.startST(validity: 3); + dynamic error; + try { + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio = setUpDio(); + await dio.fetch(req); + fail("Request should have failed but didnt"); + } on DioException catch (e) { + error = e.error; + } + + assert(error != null); + assert(error.toString() == + "SuperTokens.init must be called before using Client"); + }); + + test('More than one calls to init works', () async { + await SuperTokensTestUtils.startST(validity: 5); + try { + SuperTokens.init(apiDomain: apiBasePath); + SuperTokens.init(apiDomain: apiBasePath); + } catch (e) { + fail("Calling init more than once fails the test"); + } + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio = setUpDio(); + var resp = await dio.fetch(req); + if (resp.statusCode != 200) fail("Login req failed"); + try { + SuperTokens.init(apiDomain: apiBasePath); + } catch (e) { + fail("Calling init more than once fails the test"); + } + var userInfoResp = await dio.get("/"); + if (userInfoResp.statusCode != 200) + fail("UserInfo API returned ${userInfoResp.statusCode} "); + }); + + test("Test if refresh is called after access token expires", () async { + await SuperTokensTestUtils.startST(validity: 3); + bool failed = false; + SuperTokens.init(apiDomain: apiBasePath); + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio = setUpDio(); + var resp = await dio.fetch(req); + if (resp.statusCode != 200) fail("Login req failed"); + await Future.delayed(Duration(seconds: 5), () {}); + var userInfoResp = await dio.get("/"); + if (userInfoResp.statusCode != 200) failed = true; + + int counter = await SuperTokensTestUtils.refreshTokenCounter(); + if (counter != 1) failed = true; + + assert(!failed); + }); + + test("Test does session exist after user is loggedIn", () async { + await SuperTokensTestUtils.startST(validity: 1); + bool sessionExist = false; + SuperTokens.init(apiDomain: apiBasePath); + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio = setUpDio(); + var resp = await dio.fetch(req); + if (resp.statusCode != 200) fail("Login req failed"); + sessionExist = await SuperTokens.doesSessionExist(); + // logout + var logoutResp = await dio.post("/logout"); + if (logoutResp.statusCode != 200) fail("Logout req failed"); + sessionExist = await SuperTokens.doesSessionExist(); + assert(!sessionExist); + }); + + test("Test if not logged in the Auth API throws session expired", () async { + await SuperTokensTestUtils.startST(validity: 1); + SuperTokens.init(apiDomain: apiBasePath); + Dio dio = setUpDio(); + var resp = await dio.get("/"); + + if (resp.statusCode != 401) { + fail("API should have returned session expired (401) but didnt"); + } + }); + + test("Test that getAccessToken works correctly", () async { + await SuperTokensTestUtils.startST(validity: 5); + SuperTokens.init(apiDomain: apiBasePath); + String? accessToken = await SuperTokens.getAccessToken(); + + if (accessToken != null) { + fail("Access token should be null but isn't"); + } + + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio = setUpDio(); + var resp = await dio.fetch(req); + if (resp.statusCode != 200) fail("Login req failed"); + + accessToken = await SuperTokens.getAccessToken(); + + if (accessToken == null) { + fail("Access token is null when it should not be"); + } + + await SuperTokens.signOut(); + + accessToken = await SuperTokens.getAccessToken(); + + if (accessToken != null) { + fail("Access token should be null but isn't"); + } + }); + + test("Test that different casing for autherization header works fine", + () async { + await SuperTokensTestUtils.startST(); + SuperTokens.init(apiDomain: apiBasePath); + + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio = setUpDio(); + var resp = await dio.fetch(req); + if (resp.statusCode != 200) fail("Login req failed"); + + String? accessToken = await SuperTokens.getAccessToken(); + + dio.options.headers['Authorization'] = "Bearer $accessToken"; + var userInfoResp = await dio.get("/"); + if (userInfoResp.statusCode != 200) { + fail("User Info API failed with `Authorization`"); + } + + dio.options.headers['Authorization'] = ""; + dio.options.headers['authorization'] = "Bearer $accessToken"; + var userInfoResp2 = await dio.get(""); + if (userInfoResp2.statusCode != 200) { + fail("User info API failed with `authorization`"); + } + }); + + test("Test manually adding expired access token works normally", () async { + await SuperTokensTestUtils.startST(validity: 3); + SuperTokens.init(apiDomain: apiBasePath); + + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio = setUpDio(); + var resp = await dio.fetch(req); + if (resp.statusCode != 200) fail("Login req failed"); + + String? accessToken = await SuperTokens.getAccessToken(); + + if (accessToken == null) { + fail("Access token is null when it should not be"); + } + + await Future.delayed(Duration(seconds: 5), () {}); + + dio.options.headers['Authorization'] = "Bearer $accessToken"; + var userInfoResp = await dio.get("/"); + if (userInfoResp.statusCode != 200) { + fail("User Info API failed"); + } + int count = await SuperTokensTestUtils.refreshTokenCounter(); + if (count != 1) { + fail("refreshTokenCounter returned an invalid count"); + } + }); + + test("Test that accesstoken calls refresh correctly", () async { + await SuperTokensTestUtils.startST(validity: 3); + SuperTokens.init(apiDomain: apiBasePath); + + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio = setUpDio(); + var resp = await dio.fetch(req); + if (resp.statusCode != 200) fail("Login req failed"); + + String? accessToken = await SuperTokens.getAccessToken(); + + if (accessToken == null) { + fail("Access token is null when it should not be"); + } + + await Future.delayed(Duration(seconds: 5), () {}); + + String? newAccessToken = await SuperTokens.getAccessToken(); + + if (newAccessToken == null) { + fail("Access token is nil when it shouldnt be"); + } + + int count = await SuperTokensTestUtils.refreshTokenCounter(); + if (count != 1) { + fail("refreshTokenCounter returned invalid count"); + } + + if (accessToken == newAccessToken) { + fail("Access token after refresh is same as old access token"); + } + }); + + test("Test that old access token after signOut works fine", () async { + await SuperTokensTestUtils.startST(); + SuperTokens.init(apiDomain: apiBasePath); + + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio = setUpDio(); + var resp = await dio.fetch(req); + if (resp.statusCode != 200) fail("Login req failed"); + + String? accessToken = await SuperTokens.getAccessToken(); + + if (accessToken == null) { + fail("Access token is null when it should not be"); + } + + await SuperTokens.signOut(); + + dio.options.headers['Authorization'] = "Bearer $accessToken"; + var userInfoResp = await dio.get("/"); + if (userInfoResp.statusCode != 200) { + fail("User Info API failed"); + } + }); + + test("Test that access token and refresh token are cleared after front token is removed", () async { + await SuperTokensTestUtils.startST(); + SuperTokens.init(apiDomain: apiBasePath); + + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio = setUpDio(); + var resp = await dio.fetch(req); + if (resp.statusCode != 200) fail("Login req failed"); + + String? accessToken = await Utils.getTokenForHeaderAuth(TokenType.ACCESS); + String? refreshToken = await Utils.getTokenForHeaderAuth(TokenType.REFRESH); + + assert(accessToken != null); + assert(refreshToken != null); + + RequestOptions req2 = SuperTokensTestUtils.getLogoutAltRequestDio(); + await dio.fetch(req2); + + String? accessTokenAfter = await Utils.getTokenForHeaderAuth(TokenType.ACCESS); + String? refreshTokenAfter = await Utils.getTokenForHeaderAuth(TokenType.REFRESH); + + assert(accessTokenAfter == null); + assert(refreshTokenAfter == null); + }); + + test("Test other other domains work without Authentication", () async { + await SuperTokensTestUtils.startST(validity: 1); + SuperTokens.init(apiDomain: apiBasePath); + String url = 'https://www.google.com/'; + Dio dio = setUpDio(); + var respGoogle1 = await dio.get(url); + if (respGoogle1.statusCode! > 300) fail("external API did not work"); + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio2 = setUpDio(); + var loginResp = await dio2.fetch(req); + if (loginResp.statusCode != 200) fail("Login req failed"); + var respGoogle2 = await dio.get(url); + if (respGoogle2.statusCode! > 300) fail("external API did not work"); + // logout + var logoutResp = await dio2.post("/logout"); + if (logoutResp.statusCode != 200) fail("Logout req failed"); + var respGoogle3 = await dio.get(url); + if (respGoogle3.statusCode! > 300) fail("external API did not work"); + }); + + test('Testing multiple interceptors -- After SuperTokensInterceptorWrapper', + () async { + await SuperTokensTestUtils.startST(validity: 1); + SuperTokens.init(apiDomain: apiBasePath); + Dio dio = Dio( + BaseOptions( + baseUrl: apiBasePath, + connectTimeout: Duration(seconds: 5), + receiveTimeout: Duration(milliseconds: 500), + ), + ); + dio.interceptors.add(SuperTokensInterceptorWrapper(client: dio)); + dio.interceptors.add(HttpFormatter()); + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + var loginResp = await dio.fetch(req); + if (loginResp.statusCode != 200) fail("Login req failed"); + }); + + test('Testing multiple interceptors -- Before SuperTokensInterceptorWrapper', + () async { + await SuperTokensTestUtils.startST(validity: 1); + SuperTokens.init(apiDomain: apiBasePath); + Dio dio = Dio( + BaseOptions( + baseUrl: apiBasePath, + connectTimeout: Duration(seconds: 5), + receiveTimeout: Duration(milliseconds: 500), + ), + ); + dio.interceptors.add(HttpFormatter()); + dio.interceptors.add(SuperTokensInterceptorWrapper(client: dio)); + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + var loginResp = await dio.fetch(req); + if (loginResp.statusCode != 200) fail("Login req failed"); + }); + + test("should not ignore the auth header even if it matches the stored access token", () async { + await SuperTokensTestUtils.startST(); + SuperTokens.init(apiDomain: apiBasePath); + + RequestOptions req = SuperTokensTestUtils.getLoginRequestDio(); + Dio dio = setUpDio(); + var resp = await dio.fetch(req); + if (resp.statusCode != 200) fail("Login req failed"); + + await Future.delayed(Duration(seconds: 5), () {}); + + Utils.setToken(TokenType.ACCESS, "myOwnHeHe"); + + dio.options.headers['Authorization'] = "Bearer myOwnHeHe"; + var userInfoResp = await dio.get("/base-custom-auth"); + if (userInfoResp.statusCode != 200) { + fail("User Info API failed"); + } + }); +} diff --git a/test/diointerceptor_cookie_test.dart b/test/diointerceptor_cookie_test.dart index 964a297..8b53190 100644 --- a/test/diointerceptor_cookie_test.dart +++ b/test/diointerceptor_cookie_test.dart @@ -1,11 +1,8 @@ import 'package:dio/dio.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:supertokens_flutter/src/anti-csrf.dart'; import 'package:supertokens_flutter/src/dio-interceptor-wrapper.dart'; -import 'package:supertokens_flutter/src/front-token.dart'; import 'package:supertokens_flutter/src/supertokens.dart'; -import 'package:supertokens_flutter/src/utilities.dart'; import 'package:supertokens_flutter/supertokens.dart'; import 'test-utils.dart'; @@ -30,8 +27,8 @@ void main() { Dio dio = Dio( BaseOptions( baseUrl: apiBasePath, - connectTimeout: 5000, - receiveTimeout: 500, + connectTimeout: Duration(seconds: 5), + receiveTimeout: Duration(milliseconds: 500), ), ); dio.interceptors.add(SuperTokensInterceptorWrapper(client: dio)); @@ -87,7 +84,7 @@ void main() { Dio dio = setUpDio(); await dio.fetch(req); fail("Request should have failed but didnt"); - } on DioError catch (e) { + } on DioException catch (e) { error = e.error; } diff --git a/test/supertokens_cookies_test.dart b/test/supertokens_cookies_test.dart index 7f244e6..6b5fd92 100644 --- a/test/supertokens_cookies_test.dart +++ b/test/supertokens_cookies_test.dart @@ -3,9 +3,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:supertokens_flutter/http.dart' as http; -import 'package:supertokens_flutter/src/anti-csrf.dart'; import 'package:supertokens_flutter/src/front-token.dart'; -import 'package:supertokens_flutter/src/utilities.dart'; import 'package:supertokens_flutter/supertokens.dart'; import 'test-utils.dart'; diff --git a/test/supertokens_test.dart b/test/supertokens_test.dart index f54d8d1..b203afc 100644 --- a/test/supertokens_test.dart +++ b/test/supertokens_test.dart @@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:supertokens_flutter/http.dart' as http; -import 'package:supertokens_flutter/src/anti-csrf.dart'; import 'package:supertokens_flutter/src/front-token.dart'; import 'package:supertokens_flutter/src/utilities.dart'; import 'package:supertokens_flutter/supertokens.dart';