diff --git a/auth0_flutter/example/lib/example_app.dart b/auth0_flutter/example/lib/example_app.dart index 4c1686cf..b557c6c9 100644 --- a/auth0_flutter/example/lib/example_app.dart +++ b/auth0_flutter/example/lib/example_app.dart @@ -32,7 +32,6 @@ class _ExampleAppState extends State { Auth0Web(dotenv.env['AUTH0_DOMAIN']!, dotenv.env['AUTH0_CLIENT_ID']!); webAuth = auth0.webAuthentication(scheme: dotenv.env['AUTH0_CUSTOM_SCHEME']); - if (kIsWeb) { auth0Web.onLoad().then((final credentials) => setState(() { _output = credentials?.idToken ?? ''; diff --git a/auth0_flutter/example/pubspec.yaml b/auth0_flutter/example/pubspec.yaml index d2a18377..6a7bf754 100644 --- a/auth0_flutter/example/pubspec.yaml +++ b/auth0_flutter/example/pubspec.yaml @@ -6,8 +6,8 @@ description: Demonstrates how to use the auth0_flutter plugin. publish_to: "none" # Remove this line if you wish to publish to pub.dev environment: - sdk: ">=2.17.0 <3.0.0" - flutter: ">=3.0.0" + sdk: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions diff --git a/auth0_flutter/example/web/index.html b/auth0_flutter/example/web/index.html index 632cd421..d173e7b7 100644 --- a/auth0_flutter/example/web/index.html +++ b/auth0_flutter/example/web/index.html @@ -37,7 +37,7 @@ var serviceWorkerVersion = null; - + diff --git a/auth0_flutter/lib/src/web.dart b/auth0_flutter/lib/src/web.dart index 5560560f..1ad5b73a 100644 --- a/auth0_flutter/lib/src/web.dart +++ b/auth0_flutter/lib/src/web.dart @@ -1,2 +1,2 @@ export 'web/auth0_flutter_plugin_stub.dart' - if (dart.library.html) 'web/auth0_flutter_plugin_real.dart'; + if (dart.library.js_interop) 'web/auth0_flutter_plugin_real.dart'; diff --git a/auth0_flutter/lib/src/web/auth0_flutter_plugin_real.dart b/auth0_flutter/lib/src/web/auth0_flutter_plugin_real.dart index bb94f974..e36dca06 100644 --- a/auth0_flutter/lib/src/web/auth0_flutter_plugin_real.dart +++ b/auth0_flutter/lib/src/web/auth0_flutter_plugin_real.dart @@ -1,8 +1,9 @@ import 'dart:async'; -import 'dart:html'; +import 'dart:js_interop'; import 'package:auth0_flutter_platform_interface/auth0_flutter_platform_interface.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; +import 'package:web/web.dart'; import 'auth0_flutter_web_platform_proxy.dart'; import 'extensions/client_options_extensions.dart'; @@ -38,7 +39,7 @@ class Auth0FlutterPlugin extends Auth0FlutterWebPlatform { try { return await clientProxy!.handleRedirectCallback(); } catch (e) { - throw WebExceptionExtension.fromJsObject(e); + throw WebExceptionExtension.fromJsObject(JSObject.fromInteropObject(e)); } } @@ -48,7 +49,6 @@ class Auth0FlutterPlugin extends Auth0FlutterWebPlatform { @override Future loginWithRedirect(final LoginOptions? options) { final client = _ensureClient(); - final authParams = JsInteropUtils.stripNulls(JsInteropUtils.addCustomParams( interop.AuthorizationParams( audience: options?.audience, @@ -63,7 +63,6 @@ class Auth0FlutterPlugin extends Auth0FlutterWebPlatform { final loginOptions = interop.RedirectLoginOptions(authorizationParams: authParams); - return client.loginWithRedirect(loginOptions); } @@ -83,7 +82,7 @@ class Auth0FlutterPlugin extends Auth0FlutterWebPlatform { options?.parameters ?? {})); final popupConfig = JsInteropUtils.stripNulls(interop.PopupConfigOptions( - popup: options?.popupWindow, + popup: options?.popupWindow as JSAny?, timeoutInSeconds: options?.timeoutInSeconds)); try { @@ -98,7 +97,7 @@ class Auth0FlutterPlugin extends Auth0FlutterWebPlatform { scope: authParams.scope, audience: authParams.audience)), detailedResponse: true))); } catch (e) { - throw WebExceptionExtension.fromJsObject(e); + throw WebExceptionExtension.fromJsObject(JSObject.fromInteropObject(e)); } } @@ -115,17 +114,14 @@ class Auth0FlutterPlugin extends Auth0FlutterWebPlatform { final clientProxy = _ensureClient(); final tokenOptions = options?.toGetTokenSilentlyOptions() ?? interop.GetTokenSilentlyOptions(); - // Force this, as we always want the full detail back so that we can // return a full Credentials instance. tokenOptions.detailedResponse = true; - try { final result = await clientProxy.getTokenSilently(tokenOptions); - return CredentialsExtension.fromWeb(result); } catch (e) { - throw WebExceptionExtension.fromJsObject(e); + throw WebExceptionExtension.fromJsObject(JSObject.fromInteropObject(e)); } } @@ -136,7 +132,6 @@ class Auth0FlutterPlugin extends Auth0FlutterWebPlatform { if (clientProxy == null) { throw ArgumentError('Auth0Client has not been initialized'); } - return clientProxy!; } } diff --git a/auth0_flutter/lib/src/web/auth0_flutter_web_platform_proxy.dart b/auth0_flutter/lib/src/web/auth0_flutter_web_platform_proxy.dart index f67cf277..2295f9c7 100644 --- a/auth0_flutter/lib/src/web/auth0_flutter_web_platform_proxy.dart +++ b/auth0_flutter/lib/src/web/auth0_flutter_web_platform_proxy.dart @@ -1,4 +1,4 @@ -import 'dart:js_util'; +import 'dart:js_interop'; import 'js_interop.dart'; class Auth0FlutterWebClientProxy { @@ -7,24 +7,28 @@ class Auth0FlutterWebClientProxy { Auth0FlutterWebClientProxy({required this.client}); Future loginWithRedirect(final RedirectLoginOptions options) => - promiseToFuture(client.loginWithRedirect(options)); + JSPromiseToFuture(client.loginWithRedirect(options)).toDart; Future loginWithPopup( [final PopupLoginOptions? options, final PopupConfigOptions? config]) => - promiseToFuture(client.loginWithPopup(options, config)); + JSPromiseToFuture(client.loginWithPopup(options, config)).toDart; - Future checkSession() => promiseToFuture(client.checkSession()); + Future checkSession() => + JSPromiseToFuture(client.checkSession()).toDart; Future getTokenSilently( [final GetTokenSilentlyOptions? options]) => - promiseToFuture(client.getTokenSilently(options)); + JSPromiseToFuture(client.getTokenSilently(options)).toDart; Future handleRedirectCallback() => - promiseToFuture(client.handleRedirectCallback()); + JSPromiseToFuture(client.handleRedirectCallback()).toDart; - Future isAuthenticated() => promiseToFuture(client.isAuthenticated()); + Future isAuthenticated() async { + final jsBool = await JSPromiseToFuture(client.isAuthenticated()).toDart; + return jsBool.toDart; + } Future logout(final LogoutOptions? options) => - promiseToFuture(client.logout(options)); + JSPromiseToFuture(client.logout(options)).toDart; } diff --git a/auth0_flutter/lib/src/web/extensions/credentials_extension.dart b/auth0_flutter/lib/src/web/extensions/credentials_extension.dart index ddb1d978..cdcef97b 100644 --- a/auth0_flutter/lib/src/web/extensions/credentials_extension.dart +++ b/auth0_flutter/lib/src/web/extensions/credentials_extension.dart @@ -1,3 +1,5 @@ +import 'dart:js_interop'; + import 'package:auth0_flutter_platform_interface/auth0_flutter_platform_interface.dart'; import '../js_interop.dart'; @@ -7,11 +9,10 @@ import 'user_profile_extension.dart'; extension CredentialsExtension on Credentials { static Credentials fromWeb(final WebCredentials webCredentials) { - final expiresIn = webCredentials.expires_in as int; + final expiresIn = webCredentials.expires_in.toDartInt; final expiresAt = DateTime.now().add(Duration(seconds: expiresIn)); final claims = JWT.decode(webCredentials.id_token); final user = UserProfileExtension.fromClaims(claims); - return Credentials( idToken: webCredentials.id_token, accessToken: webCredentials.access_token, diff --git a/auth0_flutter/lib/src/web/extensions/credentials_options_extension.dart b/auth0_flutter/lib/src/web/extensions/credentials_options_extension.dart index 5cd43965..c4c013f4 100644 --- a/auth0_flutter/lib/src/web/extensions/credentials_options_extension.dart +++ b/auth0_flutter/lib/src/web/extensions/credentials_options_extension.dart @@ -1,3 +1,5 @@ +import 'dart:js_interop'; + import 'package:auth0_flutter_platform_interface/auth0_flutter_platform_interface.dart'; import '../js_interop.dart'; @@ -12,6 +14,6 @@ extension CredentialsOptionsExtension on CredentialsOptions { scope: scopes?.join(' '), audience: audience), parameters)), cacheMode: cacheMode.toString(), - timeoutInSeconds: timeoutInSeconds, + timeoutInSeconds: timeoutInSeconds?.toJS, detailedResponse: detailedResponse); } diff --git a/auth0_flutter/lib/src/web/extensions/web_exception_extensions.dart b/auth0_flutter/lib/src/web/extensions/web_exception_extensions.dart index 50d3b7f4..483a6fcb 100644 --- a/auth0_flutter/lib/src/web/extensions/web_exception_extensions.dart +++ b/auth0_flutter/lib/src/web/extensions/web_exception_extensions.dart @@ -1,15 +1,20 @@ -import 'dart:js_util'; +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; import 'package:auth0_flutter_platform_interface/auth0_flutter_platform_interface.dart'; +@JS('Object.keys') +external JSArray keys(final JSObject o); + extension WebExceptionExtension on WebException { - static WebException fromJsObject(final Object jsException) { - final error = getProperty(jsException, 'error'); - final description = getProperty(jsException, 'error_description'); - final Map details = {}; + static WebException fromJsObject(final JSObject jsException) { + final error = jsException.getProperty('error'.toJS); + final description = + jsException.getProperty('error_description'.toJS); + final Map details = {}; - objectKeys(jsException).forEach((final key) { - if (key == 'error' || key == 'error_description') return; - details[key as String] = getProperty(jsException, key); + keys(jsException).toDart.forEach((final JSString key) { + if (key.toDart == 'error' || key.toDart == 'error_description') return; + details[key.toDart] = jsException.getProperty(key); }); switch (error) { @@ -27,18 +32,18 @@ extension WebExceptionExtension on WebException { case 'unsupported_grant_type': case 'temporarily_unavailable': return WebException.authenticationError( - error, description, {'state': details['state']}); + error.toDart, description.toDart, {'state': details['state']}); case 'mfa_required': - return WebException.mfaError( - description, getProperty(jsException, 'mfaToken')); + return WebException.mfaError(description.toDart, + jsException.getProperty('mfaToken'.toJS) as String); case 'timeout': - return WebException.timeout(description); + return WebException.timeout(description.toDart); case 'cancelled': - return WebException.popupClosed(description); + return WebException.popupClosed(description.toDart); case 'missing_refresh_token': - return WebException.missingRefreshToken(description); + return WebException.missingRefreshToken(description.toDart); } - return WebException(error, description, details); + return WebException(error.toDart, description.toDart, details); } } diff --git a/auth0_flutter/lib/src/web/js_interop.dart b/auth0_flutter/lib/src/web/js_interop.dart index 9367eef1..4f3b784a 100644 --- a/auth0_flutter/lib/src/web/js_interop.dart +++ b/auth0_flutter/lib/src/web/js_interop.dart @@ -3,11 +3,11 @@ @JS('auth0') library auth0; -import 'package:js/js.dart'; +import 'dart:js_interop'; @JS() @anonymous -class AuthorizationParams { +extension type AuthorizationParams._(JSObject _) implements JSObject { external String? get audience; external String? get redirect_uri; external String? get acr_values; @@ -42,7 +42,7 @@ class AuthorizationParams { @JS() @anonymous -class RedirectLoginOptions { +extension type RedirectLoginOptions._(JSObject _) implements JSObject { external AuthorizationParams? get authorizationParams; external String? get fragment; @@ -52,29 +52,29 @@ class RedirectLoginOptions { @JS() @anonymous -abstract class Cache { - T get(final String key); - void remove(final String key); - void set(final String key, final T entry); - Future> allKeys(); +extension type Cache._(JSObject _) implements JSObject { + external JSAny get(final String key); + external void remove(final String key); + external void set(final String key, final JSAny entry); + external JSPromise> allKeys(); } @JS() @anonymous -class Auth0ClientInfo { - external Map? get env; +extension type Auth0ClientInfo._(JSObject _) implements JSObject { + external JSObject? get env; external String get name; external String get version; - external factory Auth0ClientInfo( - {final Map env, + external factory Auth0ClientInfo({ + final JSObject env, required final String name, required final String version}); } @JS() @anonymous -class Auth0ClientOptions { +extension type Auth0ClientOptions._(JSObject _) implements JSObject { external factory Auth0ClientOptions( {required final Auth0ClientInfo clientInfo, required final String domain, @@ -96,7 +96,7 @@ class Auth0ClientOptions { @JS() @anonymous -class GetTokenSilentlyAuthParams { +extension type GetTokenSilentlyAuthParams._(JSObject _) implements JSObject { external String? scope; external String? audience; @@ -106,39 +106,39 @@ class GetTokenSilentlyAuthParams { @JS() @anonymous -class GetTokenSilentlyOptions { +extension type GetTokenSilentlyOptions._(JSObject _) implements JSObject { external GetTokenSilentlyAuthParams? get authorizationParams; external String? get cacheMode; - external num? get timeoutInSeconds; + external JSNumber? get timeoutInSeconds; external bool detailedResponse; external factory GetTokenSilentlyOptions( {final GetTokenSilentlyAuthParams? authorizationParams, final String? cacheMode, - final num? timeoutInSeconds, + final JSNumber? timeoutInSeconds, final bool? detailedResponse}); } @JS() @anonymous -class WebCredentials { +extension type WebCredentials._(JSObject _) implements JSObject { external String get access_token; external String get id_token; - external num expires_in; + external JSNumber expires_in; external String? get refresh_token; external String? get scope; external factory WebCredentials( {final String access_token, final String id_token, - final num expires_in, + final JSNumber expires_in, final String? refresh_token, final String? scope}); } @JS() @anonymous -class LogoutParams { +extension type LogoutParams._(JSObject _) implements JSObject { external String? get returnTo; external bool? get federated; @@ -148,7 +148,7 @@ class LogoutParams { @JS() @anonymous -class LogoutOptions { +extension type LogoutOptions._(JSObject _) implements JSObject { external LogoutParams? get logoutParams; external factory LogoutOptions({final LogoutParams? logoutParams}); @@ -156,7 +156,7 @@ class LogoutOptions { @JS() @anonymous -class PopupLoginOptions { +extension type PopupLoginOptions._ (JSObject _) implements JSObject { external AuthorizationParams? get authorizationParams; external factory PopupLoginOptions( @@ -165,24 +165,25 @@ class PopupLoginOptions { @JS() @anonymous -class PopupConfigOptions { - external dynamic get popup; +extension type PopupConfigOptions._ (JSObject _) implements JSObject { + external JSAny? get popup; external int? get timeoutInSeconds; external factory PopupConfigOptions( - {final dynamic popup, final int? timeoutInSeconds}); + {final JSAny? popup, final int? timeoutInSeconds}); } @JS() -class Auth0Client { +extension type Auth0Client._ (JSObject _) implements JSObject { external Auth0Client(final Auth0ClientOptions options); - external Future loginWithRedirect([final RedirectLoginOptions options]); - external Future loginWithPopup( + external JSPromise loginWithRedirect( + [final RedirectLoginOptions options]); + external JSPromise loginWithPopup( [final PopupLoginOptions? options, final PopupConfigOptions? config]); - external Future handleRedirectCallback([final String? url]); - external Future checkSession(); - external Future getTokenSilently( + external JSPromise handleRedirectCallback([final String? url]); + external JSPromise checkSession(); + external JSPromise getTokenSilently( [final GetTokenSilentlyOptions? options]); - external Future isAuthenticated(); - external Future logout([final LogoutOptions? logoutParams]); + external JSPromise isAuthenticated(); + external JSPromise logout([final LogoutOptions? logoutParams]); } diff --git a/auth0_flutter/lib/src/web/js_interop_utils.dart b/auth0_flutter/lib/src/web/js_interop_utils.dart index b18d2533..a9efa31e 100644 --- a/auth0_flutter/lib/src/web/js_interop_utils.dart +++ b/auth0_flutter/lib/src/web/js_interop_utils.dart @@ -1,34 +1,35 @@ -import 'dart:js_util'; +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; + +@JS('Object.keys') +external JSArray keys(final JSObject o); class JsInteropUtils { /// Rebuilds the input object, omitting values that are null - static T stripNulls(final T obj) { - final keys = objectKeys(obj); - final output = newObject(); - - for (var i = 0; i < keys.length; i++) { - final key = keys[i] as String; - final value = getProperty(obj, key) as dynamic; + static T stripNulls(final T obj) { + final objKeys = keys(obj); + final output = JSObject(); + for (var i = 0; i < objKeys.length; i++) { + final key = objKeys[i]; + final value = obj.getProperty(key); if (value != null) { - setProperty(output, key, value); + output.setProperty(key, value); } } - return output as T; } // Adds arbitrary key/value pairs to the supplied object. // **Note**: there is no static typing for these parameters to be able // to retrieve them again. - static T addCustomParams( + static T addCustomParams( final T obj, final Map params) { params.forEach((final key, final value) { if (value != null) { - setProperty(obj, key, value); + obj.setProperty(key.toJS,value as JSAny); } }); - return obj; } } diff --git a/auth0_flutter/pubspec.yaml b/auth0_flutter/pubspec.yaml index 9b3d08d9..255b7cc0 100644 --- a/auth0_flutter/pubspec.yaml +++ b/auth0_flutter/pubspec.yaml @@ -4,8 +4,8 @@ version: 1.8.0 homepage: https://github.com/auth0/auth0-flutter environment: - sdk: ">=2.17.0 <4.0.0" - flutter: ">=3.0.0" + sdk: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" dependencies: auth0_flutter_platform_interface: ^1.8.0 @@ -13,7 +13,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - js: ">=0.6.4 <0.8.0" + web: ^1.1.0 dependency_overrides: auth0_flutter_platform_interface: diff --git a/auth0_flutter/test/web/auth0_extension_type_mocks.dart b/auth0_flutter/test/web/auth0_extension_type_mocks.dart new file mode 100644 index 00000000..f8b35b78 --- /dev/null +++ b/auth0_flutter/test/web/auth0_extension_type_mocks.dart @@ -0,0 +1,19 @@ +import 'dart:js_interop'; + +/// Mock classes to be used in with fakes created in the auth0_flutter_web_test +/// file. Post WASM migration the actual classes can't be used for +/// implementation. +/// https://dart.dev/interop/js-interop/mock +/// https://github.com/dart-lang/sdk/issues/55352#issuecomment-2672207215 +/// + +@JSExport() +class Auth0ClientImpl { + Future handleRedirectCallback([final String? url]) => throw ''; +} + +@JSExport() +class WebCredentialsImpl { + String access_token = throw ''; +} + diff --git a/auth0_flutter/test/web/auth0_flutter_web_test.dart b/auth0_flutter/test/web/auth0_flutter_web_test.dart index e224276e..8a5088ad 100644 --- a/auth0_flutter/test/web/auth0_flutter_web_test.dart +++ b/auth0_flutter/test/web/auth0_flutter_web_test.dart @@ -1,7 +1,7 @@ @Tags(['browser']) -import 'dart:js'; -import 'dart:js_util'; +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; import 'package:auth0_flutter/auth0_flutter_web.dart'; import 'package:auth0_flutter/src/web/auth0_flutter_plugin_real.dart'; @@ -12,6 +12,7 @@ import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; + import 'auth0_flutter_web_test.mocks.dart'; @GenerateMocks([Auth0FlutterWebClientProxy]) @@ -25,7 +26,7 @@ void main() { id_token: jwt, refresh_token: jwt, scope: 'openid read_messages', - expires_in: 0); + expires_in: 0.toJS); late Auth0FlutterPlugin plugin; setUp(() { @@ -37,9 +38,9 @@ void main() { }); Object createJsException(final String error, final String description) { - final jsObject = newObject(); - setProperty(jsObject, 'error', error); - setProperty(jsObject, 'error_description', description); + final jsObject = JSObject(); + jsObject.setProperty('error'.toJS, error.toJS); + jsObject.setProperty('error_description'.toJS, description.toJS); return jsObject; } diff --git a/auth0_flutter/test/web/auth0_flutter_web_test.mocks.dart b/auth0_flutter/test/web/auth0_flutter_web_test.mocks.dart index e5aadd54..b4685834 100644 --- a/auth0_flutter/test/web/auth0_flutter_web_test.mocks.dart +++ b/auth0_flutter/test/web/auth0_flutter_web_test.mocks.dart @@ -4,11 +4,13 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i4; +import 'dart:js_interop'; import 'package:auth0_flutter/src/web/auth0_flutter_web_platform_proxy.dart' as _i3; import 'package:auth0_flutter/src/web/js_interop.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; +import 'auth0_extension_type_mocks.dart'; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -21,7 +23,8 @@ import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeAuth0Client_0 extends _i1.SmartFake implements _i2.Auth0Client { +@JSExport() +class _FakeAuth0Client_0 extends _i1.SmartFake implements Auth0ClientImpl { _FakeAuth0Client_0( Object parent, Invocation parentInvocation, @@ -31,8 +34,9 @@ class _FakeAuth0Client_0 extends _i1.SmartFake implements _i2.Auth0Client { ); } +@JSExport() class _FakeWebCredentials_1 extends _i1.SmartFake - implements _i2.WebCredentials { + implements WebCredentialsImpl { _FakeWebCredentials_1( Object parent, Invocation parentInvocation, @@ -52,12 +56,12 @@ class MockAuth0FlutterWebClientProxy extends _i1.Mock } @override - _i2.Auth0Client get client => (super.noSuchMethod( + _i2.Auth0Client get client => ( + super.noSuchMethod( Invocation.getter(#client), - returnValue: _FakeAuth0Client_0( - this, - Invocation.getter(#client), - ), + returnValue:createJSInteropWrapper<_FakeAuth0Client_0> + (_FakeAuth0Client_0(this, Invocation.getter(#client), + )) as _i2.Auth0Client, ) as _i2.Auth0Client); @override _i4.Future loginWithRedirect(_i2.RedirectLoginOptions? options) => @@ -102,13 +106,11 @@ class MockAuth0FlutterWebClientProxy extends _i1.Mock #getTokenSilently, [options], ), - returnValue: _i4.Future<_i2.WebCredentials>.value(_FakeWebCredentials_1( - this, - Invocation.method( - #getTokenSilently, - [options], - ), - )), + returnValue: _i4.Future<_i2.WebCredentials>.value( + createJSInteropWrapper<_FakeWebCredentials_1>( + _FakeWebCredentials_1(this, Invocation.method( + #getTokenSilently, [options],), + )) as _i2.WebCredentials), ) as _i4.Future<_i2.WebCredentials>); @override _i4.Future handleRedirectCallback() => (super.noSuchMethod( diff --git a/auth0_flutter/test/web/extensions/credentials_extension_test.dart b/auth0_flutter/test/web/extensions/credentials_extension_test.dart index f535cdfd..40821685 100644 --- a/auth0_flutter/test/web/extensions/credentials_extension_test.dart +++ b/auth0_flutter/test/web/extensions/credentials_extension_test.dart @@ -1,5 +1,6 @@ @Tags(['browser']) +import 'dart:js_interop'; import 'package:auth0_flutter/src/web/extensions/credentials_extension.dart'; import 'package:auth0_flutter/src/web/extensions/string_extension.dart'; import 'package:auth0_flutter/src/web/js_interop.dart'; @@ -17,7 +18,7 @@ void main() { const expiresIn = 8400; const expectedTokenType = 'Bearer'; final webCredentials = WebCredentials( - access_token: accessToken, id_token: idToken, expires_in: expiresIn); + access_token: accessToken, id_token: idToken, expires_in: expiresIn.toJS); final result = CredentialsExtension.fromWeb(webCredentials); expect(result.accessToken, accessToken); @@ -40,7 +41,7 @@ void main() { final webCredentials = WebCredentials( access_token: accessToken, id_token: idToken, - expires_in: expiresIn, + expires_in: expiresIn.toJS, refresh_token: refreshToken, scope: scope); final result = CredentialsExtension.fromWeb(webCredentials); diff --git a/auth0_flutter/test/web/extensions/web_exception_extension_test.dart b/auth0_flutter/test/web/extensions/web_exception_extension_test.dart index fa98a332..8c06b2b6 100644 --- a/auth0_flutter/test/web/extensions/web_exception_extension_test.dart +++ b/auth0_flutter/test/web/extensions/web_exception_extension_test.dart @@ -1,20 +1,19 @@ @Tags(['browser']) - -import 'dart:js'; -import 'dart:js_util'; +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; import 'package:auth0_flutter/src/web/extensions/web_exception_extensions.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { - Object createJsException(final String error, final String description, - {final Map? additionalProps}) { - final jsObject = newObject(); - setProperty(jsObject, 'error', error); - setProperty(jsObject, 'error_description', description); + JSObject createJsException(final String error, final String description, + {final Map? additionalProps}) { + final jsObject = JSObject(); + jsObject.setProperty('error'.toJS, error.toJS); + jsObject.setProperty('error_description'.toJS, description.toJS); if (additionalProps != null) { for (final element in additionalProps.entries) { - setProperty(jsObject, element.key, element.value); + jsObject.setProperty(element.key.toJS, element.value); } } @@ -24,7 +23,10 @@ void main() { test('additional props are added to the details collection', () { final exception = createJsException( 'authentication_error', 'A test authentication error', - additionalProps: {'prop-1': 'Property 1', 'prop-2': 'Property 2'}); + additionalProps: { + 'prop-1': 'Property 1'.toJS, + 'prop-2': 'Property 2'.toJS + }); final webException = WebExceptionExtension.fromJsObject(exception); @@ -36,10 +38,9 @@ void main() { test('mfa_required exception is created', () { final exception = createJsException('mfa_required', 'MFA is required', - additionalProps: {'mfaToken': 'abc123'}); + additionalProps: {'mfaToken': 'abc123'.toJS}); final webException = WebExceptionExtension.fromJsObject(exception); - expect(webException.code, 'MFA_REQUIRED'); expect(webException.message, 'MFA is required'); expect(webException.details['mfaToken'], 'abc123'); @@ -102,7 +103,7 @@ void main() { test('AUTHENTICATION_ERROR is captured with state only', () { final exception = createJsException('invalid_grant', 'Invalid grant', - additionalProps: {'state': '123', 'appState': '456'}); + additionalProps: {'state': '123'.toJS, 'appState': '456'.toJS}); final webException = WebExceptionExtension.fromJsObject(exception); diff --git a/auth0_flutter_platform_interface/pubspec.yaml b/auth0_flutter_platform_interface/pubspec.yaml index a0abd970..c3c236c2 100644 --- a/auth0_flutter_platform_interface/pubspec.yaml +++ b/auth0_flutter_platform_interface/pubspec.yaml @@ -5,13 +5,14 @@ version: 1.8.0 homepage: https://github.com/auth0/auth0-flutter environment: - sdk: ">=2.17.0 <4.0.0" - flutter: ">=3.0.0" + sdk: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" dependencies: flutter: sdk: flutter plugin_platform_interface: ^2.0.0 + web: ^1.1.0 dev_dependencies: build_runner: ^2.1.8