diff --git a/packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart b/packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart index 5cbba1d3c996..c68376353d3e 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/firebase_auth_web.dart @@ -4,7 +4,7 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:html'; +import 'dart:js_interop'; import 'package:firebase_auth_platform_interface/firebase_auth_platform_interface.dart'; import 'package:firebase_auth_web/src/firebase_auth_web_multi_factor.dart'; @@ -16,6 +16,7 @@ import 'package:firebase_core_web/firebase_core_web_interop.dart' as core_interop; import 'package:flutter/foundation.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; +import 'package:web/web.dart' as web; import 'src/firebase_auth_web_confirmation_result.dart'; import 'src/firebase_auth_web_recaptcha_verifier_factory.dart'; @@ -90,9 +91,9 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { ensurePluginInitialized: (firebaseApp) async { final authDelegate = auth_interop.getAuthInstance(firebaseApp); // if localhost, and emulator was previously set in localStorage, use it - if (window.location.hostname == 'localhost' && kDebugMode) { - final String? emulatorOrigin = - window.sessionStorage[getOriginName(firebaseApp.name)]; + if (web.window.location.hostname == 'localhost' && kDebugMode) { + final String? emulatorOrigin = web.window.sessionStorage + .getItem(getOriginName(firebaseApp.name)); if (emulatorOrigin != null) { try { @@ -327,7 +328,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { bool? forceRecaptchaFlow, }) async { delegate.settings.appVerificationDisabledForTesting = - appVerificationDisabledForTesting; + appVerificationDisabledForTesting?.toJS; } @override @@ -464,7 +465,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { try { // Get current session storage value final String? emulatorOrigin = - window.sessionStorage[getOriginName(delegate.app.name)]; + web.window.sessionStorage.getItem(getOriginName(delegate.app.name)); // The generic platform interface is with host and port split to // centralize logic between android/ios native, but web takes the @@ -481,11 +482,12 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform { // Save to session storage so that the emulator is used on refresh // only in debug mode if (kDebugMode) { - window.sessionStorage[getOriginName(delegate.app.name)] = origin; + web.window.sessionStorage + .setItem(getOriginName(delegate.app.name), origin); } } catch (e) { if (e is auth_interop.AuthError) { - final String code = e.code; + final String code = e.code.toDart; // this catches Firebase Error from web that occurs after hot reloading & hot restarting if (code != 'auth/emulator-config-failed') { throw getFirebaseAuthException(e); diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_recaptcha_verifier_factory.dart b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_recaptcha_verifier_factory.dart index 73a475a7bd55..b5cf8a2e2d56 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_recaptcha_verifier_factory.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_recaptcha_verifier_factory.dart @@ -4,10 +4,10 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:html'; import 'package:firebase_auth_platform_interface/firebase_auth_platform_interface.dart'; import 'package:firebase_auth_web/firebase_auth_web.dart'; +import 'package:web/web.dart' as web; import 'interop/auth.dart' as auth_interop; import 'utils/web_utils.dart'; @@ -65,15 +65,16 @@ class RecaptchaVerifierFactoryWeb extends RecaptchaVerifierFactoryPlatform { if (container == null || container.isEmpty) { parameters['size'] = 'invisible'; - Element? el = window.document.getElementById(_kInvisibleElementId); + web.Element? el = + web.window.document.getElementById(_kInvisibleElementId); // If an existing element exists, something may have already been rendered. if (el != null) { el.remove(); } - window.document.documentElement!.children - .add(DivElement()..id = _kInvisibleElementId); + web.window.document.documentElement! + .appendChild(web.Element()..id = _kInvisibleElementId); element = _kInvisibleElementId; } else { @@ -81,7 +82,7 @@ class RecaptchaVerifierFactoryWeb extends RecaptchaVerifierFactoryPlatform { parameters['theme'] = convertRecaptchaVerifierTheme(theme); assert( - window.document.getElementById(container) != null, + web.window.document.getElementById(container) != null, 'An exception was thrown whilst creating a RecaptchaVerifier instance. No DOM element with an ID of $container could be found.', ); @@ -129,7 +130,7 @@ class RecaptchaVerifierFactoryWeb extends RecaptchaVerifierFactoryPlatform { @override void clear() { _delegate.clear(); - window.document.getElementById(_kInvisibleElementId)?.remove(); + web.window.document.getElementById(_kInvisibleElementId)?.remove(); } @override diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user.dart b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user.dart index 6746bfd89fc5..b22f26d46f43 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/firebase_auth_web_user.dart @@ -4,7 +4,8 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:js'; +import 'dart:js_interop' as js_interop; +import 'dart:js_interop_unsafe'; import 'package:firebase_auth_platform_interface/firebase_auth_platform_interface.dart'; import 'package:firebase_auth_web/src/firebase_auth_web_user_credential.dart'; @@ -31,12 +32,18 @@ class UserWeb extends UserPlatform { isEmailVerified: _webUser.emailVerified, isAnonymous: _webUser.isAnonymous, creationTimestamp: _webUser.metadata.creationTime != null - ? context['Date'] - .callMethod('parse', [_webUser.metadata.creationTime]) + ? (js_interop.globalContext.getProperty('Date'.toJS)! + as js_interop.JSObject) + .callMethod( + 'parse'.toJS, _webUser.metadata.creationTime) + .toDartInt : null, lastSignInTimestamp: _webUser.metadata.lastSignInTime != null - ? context['Date'] - .callMethod('parse', [_webUser.metadata.lastSignInTime]) + ? (js_interop.globalContext.getProperty('Date'.toJS)! + as js_interop.JSObject) + .callMethod( + 'parse'.toJS, _webUser.metadata.lastSignInTime) + .toDartInt : null, phoneNumber: _webUser.phoneNumber, photoUrl: _webUser.photoURL, @@ -278,16 +285,16 @@ class UserWeb extends UserPlatform { if (profile.containsKey('displayName') && profile.containsKey('photoURL')) { newProfile = auth_interop.UserProfile( - displayName: profile['displayName'], - photoURL: profile['photoURL'], + displayName: profile['displayName']?.toJS, + photoURL: profile['photoURL']?.toJS, ); } else if (profile.containsKey('displayName')) { newProfile = auth_interop.UserProfile( - displayName: profile['displayName'], + displayName: profile['displayName']?.toJS, ); } else { newProfile = auth_interop.UserProfile( - photoURL: profile['photoURL'], + photoURL: profile['photoURL']?.toJS, ); } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth.dart b/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth.dart index c885dd0afb6e..fd5d29462e4e 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth.dart @@ -7,12 +7,12 @@ // ignore_for_file: public_member_api_docs import 'dart:async'; +import 'dart:js_interop'; import 'package:firebase_auth_platform_interface/firebase_auth_platform_interface.dart'; import 'package:firebase_core_web/firebase_core_web_interop.dart' hide jsify, dartify; import 'package:http_parser/http_parser.dart'; -import 'package:js/js.dart'; import 'auth_interop.dart' as auth_interop; import 'utils/utils.dart'; @@ -42,22 +42,22 @@ Auth getAuthInstance(App app) { class UserInfo extends JsObjectWrapper { /// User's display name. - String? get displayName => jsObject.displayName; + String? get displayName => jsObject.displayName?.toDart; /// User's e-mail address. - String? get email => jsObject.email; + String? get email => jsObject.email?.toDart; /// The user's E.164 formatted phone number (if available). - String? get phoneNumber => jsObject.phoneNumber; + String? get phoneNumber => jsObject.phoneNumber?.toDart; /// User's profile picture URL. - String? get photoURL => jsObject.photoURL; + String? get photoURL => jsObject.photoURL?.toDart; /// User's authentication provider ID. - String get providerId => jsObject.providerId; + String get providerId => jsObject.providerId.toDart; /// User's unique ID. - String get uid => jsObject.uid; + String get uid => jsObject.uid.toDart; /// Creates a new UserInfo from a [jsObject]. UserInfo._fromJsObject(auth_interop.UserInfoJsImpl jsObject) @@ -71,21 +71,21 @@ class User extends UserInfo { static final _expando = Expando(); @override - String get uid => jsObject.uid; + String get uid => jsObject.uid.toDart; /// If the user's email address has been already verified. - bool get emailVerified => jsObject.emailVerified; + bool get emailVerified => jsObject.emailVerified.toDart; /// If the user is anonymous. - bool get isAnonymous => jsObject.isAnonymous; + bool get isAnonymous => jsObject.isAnonymous.toDart; - String? get tenantId => jsObject.tenantId; + String? get tenantId => jsObject.tenantId?.toDart; /// Non-null additional metadata about the user. auth_interop.UserMetadata get metadata => jsObject.metadata; /// List of additional provider-specific information about the user. - List get providerData => jsObject.providerData + List get providerData => jsObject.providerData.toDart // explicitly typing the param as dynamic to work-around // https://github.com/dart-lang/sdk/issues/33537 // ignore: unnecessary_lambdas, false positive, data is dynamic @@ -94,7 +94,7 @@ class User extends UserInfo { .toList(); /// Refresh token for the user account. - String get refreshToken => jsObject.refreshToken; + String get refreshToken => jsObject.refreshToken.toDart; /// Creates a new User from a [jsObject]. /// @@ -113,7 +113,7 @@ class User extends UserInfo { : super._fromJsObject(jsObject); /// Deletes and signs out the user. - Future delete() => handleThenable(jsObject.delete()); + Future delete() => jsObject.delete().toDart; /// Returns a JWT token used to identify the user to a Firebase service. /// @@ -123,43 +123,44 @@ class User extends UserInfo { /// It forces refresh regardless of token expiration if [forceRefresh] /// parameter is `true`. Future getIdToken([bool forceRefresh = false]) => - handleThenable(jsObject.getIdToken(forceRefresh)); + jsObject.getIdToken(forceRefresh.toJS).toDart as Future; /// Links the user account with the given credentials, and returns any /// available additional user information, such as user name. Future linkWithCredential( auth_interop.OAuthCredential? credential) => - handleThenable(auth_interop.linkWithCredential(jsObject, credential)) + (auth_interop.linkWithCredential(jsObject, credential).toDart + as Future) .then(UserCredential.fromJsObject); /// Links the user account with the given [phoneNumber] in E.164 format /// (e.g. +16505550101) and [applicationVerifier]. Future linkWithPhoneNumber( String phoneNumber, ApplicationVerifier applicationVerifier) => - handleThenable( - auth_interop.linkWithPhoneNumber( - jsObject, phoneNumber, applicationVerifier.jsObject), - ).then(ConfirmationResult.fromJsObject); + (auth_interop + .linkWithPhoneNumber( + jsObject, phoneNumber.toJS, applicationVerifier.jsObject) + .toDart as Future) + .then(ConfirmationResult.fromJsObject); /// Links the authenticated [provider] to the user account using /// a pop-up based OAuth flow. /// It returns the [UserCredential] information if linking is successful. Future linkWithPopup(AuthProvider provider) => - handleThenable(auth_interop.linkWithPopup(jsObject, provider.jsObject)) - .then(UserCredential.fromJsObject); + auth_interop.linkWithPopup(jsObject, provider.jsObject).toDart + as Future; /// Links the authenticated [provider] to the user account using /// a full-page redirect flow. - Future linkWithRedirect(AuthProvider provider) => handleThenable( - auth_interop.linkWithRedirect(jsObject, provider.jsObject)); + Future linkWithRedirect(AuthProvider provider) => + auth_interop.linkWithRedirect(jsObject, provider.jsObject).toDart; /// Re-authenticates a user using a fresh credential, and returns any /// available additional user information, such as user name. Future reauthenticateWithCredential( auth_interop.OAuthCredential credential) => - handleThenable( - auth_interop.reauthenticateWithCredential(jsObject, credential)) - .then(UserCredential.fromJsObject); + auth_interop.reauthenticateWithCredential(jsObject, credential).toDart + as Future; /// Re-authenticates a user using a fresh credential. /// Use before operations such as [updatePassword] that require tokens @@ -168,26 +169,26 @@ class User extends UserInfo { /// The user's phone number is in E.164 format (e.g. +16505550101). Future reauthenticateWithPhoneNumber( String phoneNumber, ApplicationVerifier applicationVerifier) => - handleThenable(auth_interop.reauthenticateWithPhoneNumber( - jsObject, phoneNumber, applicationVerifier.jsObject)) - .then(ConfirmationResult.fromJsObject); + auth_interop + .reauthenticateWithPhoneNumber( + jsObject, phoneNumber.toJS, applicationVerifier.jsObject) + .toDart as Future; /// Reauthenticates a user with the specified provider using /// a pop-up based OAuth flow. /// It returns the [UserCredential] information if reauthentication is successful. Future reauthenticateWithPopup(AuthProvider provider) => - handleThenable( - auth_interop.reauthenticateWithPopup(jsObject, provider.jsObject)) - .then(UserCredential.fromJsObject); + auth_interop.reauthenticateWithPopup(jsObject, provider.jsObject).toDart + as Future; /// Reauthenticates a user with the specified OAuth [provider] using /// a full-page redirect flow. - Future reauthenticateWithRedirect(AuthProvider provider) => - handleThenable( - auth_interop.reauthenticateWithRedirect(jsObject, provider.jsObject)); + Future reauthenticateWithRedirect(AuthProvider provider) => auth_interop + .reauthenticateWithRedirect(jsObject, provider.jsObject) + .toDart; /// If signed in, it refreshes the current user. - Future reload() => handleThenable(jsObject.reload()); + Future reload() => jsObject.reload().toDart; /// Sends an e-mail verification to a user. /// @@ -209,46 +210,49 @@ class User extends UserInfo { /// they are configured in the same Firebase Auth project used. Future sendEmailVerification( [auth_interop.ActionCodeSettings? actionCodeSettings]) => - handleThenable( - auth_interop.sendEmailVerification(jsObject, actionCodeSettings)); + auth_interop.sendEmailVerification(jsObject, actionCodeSettings).toDart; /// Sends a verification email to a new email address. The user's email will be updated to the new one /// after being verified. Future verifyBeforeUpdateEmail(String newEmail, [auth_interop.ActionCodeSettings? actionCodeSettings]) => - handleThenable(auth_interop.verifyBeforeUpdateEmail( - jsObject, newEmail, actionCodeSettings)); + auth_interop + .verifyBeforeUpdateEmail(jsObject, newEmail.toJS, actionCodeSettings) + .toDart; /// Unlinks a provider with [providerId] from a user account. - Future unlink(String providerId) => - handleThenable(auth_interop.unlink(jsObject, providerId)) - .then((user) => User.getInstance(user)!); + Future unlink(String providerId) => auth_interop + .unlink(jsObject, providerId.toJS) + .toDart + .then((user) => User.getInstance(user! as auth_interop.UserJsImpl)!); /// Updates the user's e-mail address to [newEmail]. Future updateEmail(String newEmail) => - handleThenable(auth_interop.updateEmail(jsObject, newEmail)); + auth_interop.updateEmail(jsObject, newEmail.toJS).toDart; /// Updates the user's password to [newPassword]. /// Requires the user to have recently signed in. If not, ask the user /// to authenticate again and then use [reauthenticate()]. Future updatePassword(String newPassword) => - handleThenable(auth_interop.updatePassword(jsObject, newPassword)); + auth_interop.updatePassword(jsObject, newPassword.toJS).toDart; /// Updates the user's phone number. Future updatePhoneNumber( auth_interop.OAuthCredential? phoneCredential) => - handleThenable(auth_interop.updatePhoneNumber(jsObject, phoneCredential)); + auth_interop.updatePhoneNumber(jsObject, phoneCredential).toDart; /// Updates a user's profile data. Future updateProfile(auth_interop.UserProfile profile) => - handleThenable(auth_interop.updateProfile(jsObject, profile)); + auth_interop.updateProfile(jsObject, profile).toDart; + /// Retrieves the ID token result for the current user, optionally forcing a refresh. Future getIdTokenResult([bool? forceRefresh]) { final promise = forceRefresh == null ? jsObject.getIdTokenResult() - : jsObject.getIdTokenResult(forceRefresh); + : jsObject.getIdTokenResult(forceRefresh.toJS); - return handleThenable(promise).then(IdTokenResult._fromJsObject); + return (promise.toDart as Future) + .then(IdTokenResult._fromJsObject); } /// Returns a JSON-serializable representation of this object. @@ -275,26 +279,26 @@ class IdTokenResult extends JsObjectWrapper { /// /// This is the time the user authenticated (signed in) and not the time the /// token was refreshed. - DateTime get authTime => parseHttpDate(jsObject.authTime); + DateTime get authTime => parseHttpDate(jsObject.authTime.toDart); /// The entire payload claims of the ID token including the standard reserved /// claims as well as the custom claims. Map? get claims => dartify(jsObject.claims); /// The ID token expiration time. - DateTime get expirationTime => parseHttpDate(jsObject.expirationTime); + DateTime get expirationTime => parseHttpDate(jsObject.expirationTime.toDart); /// The ID token issued at time. - DateTime get issuedAtTime => parseHttpDate(jsObject.issuedAtTime); + DateTime get issuedAtTime => parseHttpDate(jsObject.issuedAtTime.toDart); /// The sign-in provider through which the ID token was obtained (anonymous, /// custom, phone, password, etc). /// /// Note, this does not map to provider IDs. - String get signInProvider => jsObject.signInProvider; + String get signInProvider => jsObject.signInProvider.toDart; /// The Firebase Auth ID token JWT string. - String get token => jsObject.token; + String get token => jsObject.token.toDart; } /// The Firebase Auth service class. @@ -311,11 +315,11 @@ class Auth extends JsObjectWrapper { // Returns the current tenantId for the instance. String? get tenantId { - return jsObject.tenantId; + return jsObject.tenantId?.toDart; } set tenantId(String? tenantId) { - jsObject.tenantId = tenantId; + jsObject.tenantId = tenantId?.toJS; } /// The current Auth instance's language code. @@ -326,10 +330,10 @@ class Auth extends JsObjectWrapper { /// SMS templates for phone authentication, reCAPTCHA verifier and OAuth /// popup/redirect operations provided the specified providers support /// localization with the language code specified. - String get languageCode => jsObject.languageCode; + String get languageCode => jsObject.languageCode.toDart; set languageCode(String? s) { - jsObject.languageCode = s; + jsObject.languageCode = s?.toJS; } // set settings(auth_interop.AuthSettings s) { @@ -346,21 +350,22 @@ class Auth extends JsObjectWrapper { /// in `_initUser` and add it manually to the `_changeController`. Future onWaitInitState() async { final completer = Completer(); - final nextWrapper = allowInterop((auth_interop.UserJsImpl? user) { + final nextWrapper = (auth_interop.UserJsImpl? user) { _initUser = User.getInstance(user); completer.complete(); - }); + }; - final errorWrapper = allowInterop((e) => _changeController!.addError(e)); + final errorWrapper = (JSAny e) => _changeController!.addError(e); - final unsubscribe = jsObject.onAuthStateChanged(nextWrapper, errorWrapper); + final unsubscribe = + jsObject.onAuthStateChanged(nextWrapper.toJS, errorWrapper.toJS); await completer.future; - unsubscribe(); + await (unsubscribe.dartify()! as Future Function())(); } - Func0? _onAuthUnsubscribe; + JSFunction? _onAuthUnsubscribe; // TODO(rrousselGit): fix memory leak – the controller isn't closed even in onCancel // ignore: close_sinks StreamController? _changeController; @@ -373,20 +378,20 @@ class Auth extends JsObjectWrapper { /// If the value is `null`, there is no signed-in user. Stream get onAuthStateChanged { if (_changeController == null) { - final nextWrapper = allowInterop((auth_interop.UserJsImpl? user) { + final nextWrapper = (auth_interop.UserJsImpl? user) { _changeController!.add(User.getInstance(user)); - }); + }; - final errorWrapper = allowInterop((e) => _changeController!.addError(e)); + final errorWrapper = (JSAny e) => _changeController!.addError(e); void startListen() { assert(_onAuthUnsubscribe == null); _onAuthUnsubscribe = - jsObject.onAuthStateChanged(nextWrapper, errorWrapper); + jsObject.onAuthStateChanged(nextWrapper.toJS, errorWrapper.toJS); } void stopListen() { - _onAuthUnsubscribe!(); + (_onAuthUnsubscribe!.dartify()! as Function)(); _onAuthUnsubscribe = null; } @@ -401,7 +406,7 @@ class Auth extends JsObjectWrapper { return _changeController!.stream; } - Func0? _onIdTokenChangedUnsubscribe; + JSFunction? _onIdTokenChangedUnsubscribe; // TODO(rrousselGit): fix memory leak – the controller isn't closed even in onCancel // ignore: close_sinks StreamController? _idTokenChangedController; @@ -414,21 +419,20 @@ class Auth extends JsObjectWrapper { /// If the value is `null`, there is no signed-in user. Stream get onIdTokenChanged { if (_idTokenChangedController == null) { - final nextWrapper = allowInterop((auth_interop.UserJsImpl? user) { + final nextWrapper = (auth_interop.UserJsImpl? user) { _idTokenChangedController!.add(User.getInstance(user)); - }); + }; - final errorWrapper = - allowInterop((e) => _idTokenChangedController!.addError(e)); + final errorWrapper = (JSAny e) => _idTokenChangedController!.addError(e); void startListen() { assert(_onIdTokenChangedUnsubscribe == null); _onIdTokenChangedUnsubscribe = - jsObject.onIdTokenChanged(nextWrapper, errorWrapper); + jsObject.onIdTokenChanged(nextWrapper.toJS, errorWrapper.toJS); } void stopListen() { - _onIdTokenChangedUnsubscribe!(); + (_onIdTokenChangedUnsubscribe!.dartify()! as Function)(); _onIdTokenChangedUnsubscribe = null; } @@ -452,19 +456,19 @@ class Auth extends JsObjectWrapper { /// Applies a verification [oobCode] sent to the user by e-mail or by other /// out-of-band mechanism. Future applyActionCode(String oobCode) => - handleThenable(auth_interop.applyActionCode(jsObject, oobCode)); + auth_interop.applyActionCode(jsObject, oobCode.toJS).toDart; /// Checks a verification [code] sent to the user by e-mail or by other /// out-of-band mechanism. /// It returns [ActionCodeInfo], metadata about the code. Future checkActionCode(String code) => - handleThenable(auth_interop.checkActionCode(jsObject, code)); + (auth_interop.checkActionCode(jsObject, code.toJS).toDart) + as Future; /// Completes password reset process with a [code] and a [newPassword]. - Future confirmPasswordReset(String code, String newPassword) => - handleThenable( - auth_interop.confirmPasswordReset(jsObject, code, newPassword), - ); + Future confirmPasswordReset(String code, String newPassword) => auth_interop + .confirmPasswordReset(jsObject, code.toJS, newPassword.toJS) + .toDart; /// Creates a new user account associated with the specified email address and /// password. @@ -482,11 +486,11 @@ class Auth extends JsObjectWrapper { String email, String password, ) async { - final u = await handleThenable( - auth_interop.createUserWithEmailAndPassword(jsObject, email, password), - ); + final u = await auth_interop + .createUserWithEmailAndPassword(jsObject, email.toJS, password.toJS) + .toDart; - return UserCredential.fromJsObject(u); + return UserCredential.fromJsObject(u! as auth_interop.UserCredentialJsImpl); } /// Gets the list of possible sign in methods for the given email address. @@ -494,22 +498,27 @@ class Auth extends JsObjectWrapper { /// This is useful to differentiate methods of sign-in for the same provider, /// eg. EmailAuthProvider which has 2 methods of sign-in, email/password and /// email/link. - Future> fetchSignInMethodsForEmail(String email) => - handleThenable(auth_interop.fetchSignInMethodsForEmail(jsObject, email)) - .then(List.from); + Future> fetchSignInMethodsForEmail(String email) => auth_interop + .fetchSignInMethodsForEmail(jsObject, email.toJS) + .toDart + .then((value) => List.from(value! as List)); /// Checks if an incoming link is a sign-in with email link. bool isSignInWithEmailLink(String emailLink) => - auth_interop.isSignInWithEmailLink(emailLink); + auth_interop.isSignInWithEmailLink(emailLink.toJS).toDart; /// Returns a [UserCredential] from the redirect-based sign in flow. /// If sign is successful, returns the signed in user. Or fails with an error /// if sign is unsuccessful. /// The [UserCredential] with a null [User] is returned if no redirect /// operation was called. - Future getRedirectResult() => - handleThenable(auth_interop.getRedirectResult(jsObject)).then( - (value) => value == null ? null : UserCredential.fromJsObject(value)); + Future getRedirectResult() => auth_interop + .getRedirectResult(jsObject) + .toDart + .then((value) => value == null + ? null + : UserCredential.fromJsObject( + value as auth_interop.UserCredentialJsImpl)); /// Sends a sign-in email link to the user with the specified email. /// @@ -523,8 +532,9 @@ class Auth extends JsObjectWrapper { /// the email link supplied in the email sent to the user. Future sendSignInLinkToEmail(String email, [auth_interop.ActionCodeSettings? actionCodeSettings]) => - handleThenable(auth_interop.sendSignInLinkToEmail( - jsObject, email, actionCodeSettings)); + auth_interop + .sendSignInLinkToEmail(jsObject, email.toJS, actionCodeSettings) + .toDart; /// Changes the current type of persistence on the current Auth instance for /// the currently saved Auth session and applies this type of persistence @@ -559,7 +569,7 @@ class Auth extends JsObjectWrapper { instance = auth_interop.inMemoryPersistence; break; } - return handleThenable(auth_interop.setPersistence(jsObject, instance)); + return auth_interop.setPersistence(jsObject, instance).toDart; } /// Sends a password reset e-mail to the given [email]. @@ -583,24 +593,28 @@ class Auth extends JsObjectWrapper { /// they are configured in the same Firebase Auth project used. Future sendPasswordResetEmail(String email, [auth_interop.ActionCodeSettings? actionCodeSettings]) => - handleThenable(auth_interop.sendPasswordResetEmail( - jsObject, email, actionCodeSettings)); + auth_interop + .sendPasswordResetEmail(jsObject, email.toJS, actionCodeSettings) + .toDart; /// Asynchronously signs in with the given credentials, and returns any /// available additional user information, such as user name. Future signInWithCredential( auth_interop.OAuthCredential credential) => - handleThenable(auth_interop.signInWithCredential(jsObject, credential)) - .then(UserCredential.fromJsObject); + auth_interop.signInWithCredential(jsObject, credential).toDart.then( + (value) => UserCredential.fromJsObject( + value! as auth_interop.UserCredentialJsImpl)); /// Asynchronously signs in as an anonymous user. // // If there is already an anonymous user signed in, that user will be // returned; otherwise, a new anonymous user identity will be created and // returned. - Future signInAnonymously() => - handleThenable(auth_interop.signInAnonymously(jsObject)) - .then(UserCredential.fromJsObject); + Future signInAnonymously() => auth_interop + .signInAnonymously(jsObject) + .toDart + .then((value) => UserCredential.fromJsObject( + value! as auth_interop.UserCredentialJsImpl)); /// Asynchronously signs in using a custom token. /// @@ -609,9 +623,11 @@ class Auth extends JsObjectWrapper { /// /// Fails with an error if the token is invalid, expired, or not accepted by /// the Firebase Auth service. - Future signInWithCustomToken(String token) => - handleThenable(auth_interop.signInWithCustomToken(jsObject, token)) - .then(UserCredential.fromJsObject); + Future signInWithCustomToken(String token) => auth_interop + .signInWithCustomToken(jsObject, token.toJS) + .toDart + .then((value) => UserCredential.fromJsObject( + value! as auth_interop.UserCredentialJsImpl)); /// Signs in a user asynchronously using a custom [token] and returns any /// additional user info data or credentials. @@ -637,15 +653,19 @@ class Auth extends JsObjectWrapper { /// Firebase project. Future signInWithEmailAndPassword( String email, String password) => - handleThenable(auth_interop.signInWithEmailAndPassword( - jsObject, email, password)) - .then(UserCredential.fromJsObject); + auth_interop + .signInWithEmailAndPassword(jsObject, email.toJS, password.toJS) + .toDart + .then((value) => UserCredential.fromJsObject( + value! as auth_interop.UserCredentialJsImpl)); /// Signs in using [email] and [emailLink] link. Future signInWithEmailLink(String email, String emailLink) => - handleThenable( - auth_interop.signInWithEmailLink(jsObject, email, emailLink)) - .then(UserCredential.fromJsObject); + auth_interop + .signInWithEmailLink(jsObject, email.toJS, emailLink.toJS) + .toDart + .then((value) => UserCredential.fromJsObject( + value! as auth_interop.UserCredentialJsImpl)); /// Asynchronously signs in using a phone number in E.164 format /// (e.g. +16505550101). @@ -659,23 +679,28 @@ class Auth extends JsObjectWrapper { /// The Firebase Auth SDK includes a reCAPTCHA-based implementation, [RecaptchaVerifier]. Future signInWithPhoneNumber( String phoneNumber, ApplicationVerifier applicationVerifier) => - handleThenable(auth_interop.signInWithPhoneNumber( - jsObject, phoneNumber, applicationVerifier.jsObject)) - .then(ConfirmationResult.fromJsObject); + auth_interop + .signInWithPhoneNumber( + jsObject, phoneNumber.toJS, applicationVerifier.jsObject) + .toDart + .then((value) => ConfirmationResult.fromJsObject( + value! as auth_interop.ConfirmationResultJsImpl)); /// Signs in using a popup-based OAuth authentication flow with the /// given [provider]. /// Returns [UserCredential] if successful, or an error object if unsuccessful. - Future signInWithPopup(AuthProvider provider) => - handleThenable(auth_interop.signInWithPopup(jsObject, provider.jsObject)) - .then(UserCredential.fromJsObject); + Future signInWithPopup(AuthProvider provider) => auth_interop + .signInWithPopup(jsObject, provider.jsObject) + .toDart + .then((value) => UserCredential.fromJsObject( + value! as auth_interop.UserCredentialJsImpl)); /// Signs in using a full-page redirect flow with the given [provider]. - Future signInWithRedirect(AuthProvider provider) => handleThenable( - auth_interop.signInWithRedirect(jsObject, provider.jsObject)); + Future signInWithRedirect(AuthProvider provider) => + auth_interop.signInWithRedirect(jsObject, provider.jsObject).toDart; /// Signs out the current user. - Future signOut() => handleThenable(jsObject.signOut()); + Future signOut() => jsObject.signOut().toDart; /// Configures the Auth instance to work with a local emulator /// @@ -684,7 +709,7 @@ class Auth extends JsObjectWrapper { /// Note: must be called before using auth methods, do not use /// with production credentials as local connections are unencrypted void useAuthEmulator(String origin) => - auth_interop.connectAuthEmulator(jsObject, origin); + auth_interop.connectAuthEmulator(jsObject, origin.toJS); /// Sets the current language to the default device/browser preference. void useDeviceLanguage() => auth_interop.useDeviceLanguage(jsObject); @@ -693,7 +718,8 @@ class Auth extends JsObjectWrapper { /// or other out-of-band mechanism. /// Returns the user's e-mail address if valid. Future verifyPasswordResetCode(String code) => - handleThenable(auth_interop.verifyPasswordResetCode(jsObject, code)); + auth_interop.verifyPasswordResetCode(jsObject, code.toJS).toDart + as Future; } /// Represents an auth provider. @@ -702,7 +728,7 @@ class Auth extends JsObjectWrapper { abstract class AuthProvider extends JsObjectWrapper { /// Provider id. - String get providerId => jsObject.providerId; + String get providerId => jsObject.providerId.toDart; /// Creates a new AuthProvider from a [jsObject]. AuthProvider.fromJsObject(T jsObject) : super.fromJsObject(jsObject); @@ -713,7 +739,8 @@ abstract class AuthProvider /// See: . class EmailAuthProvider extends AuthProvider { - static String PROVIDER_ID = auth_interop.EmailAuthProviderJsImpl.PROVIDER_ID; + static String PROVIDER_ID = + auth_interop.EmailAuthProviderJsImpl.PROVIDER_ID.toDart; /// Creates a new EmailAuthProvider. factory EmailAuthProvider() => @@ -726,14 +753,14 @@ class EmailAuthProvider /// Creates a credential for e-mail. static auth_interop.OAuthCredential credential( String email, String password) => - auth_interop.EmailAuthProviderJsImpl.credential(email, password) + auth_interop.EmailAuthProviderJsImpl.credential(email.toJS, password.toJS) as auth_interop.OAuthCredential; /// Creates a credential for e-mail with link. static auth_interop.OAuthCredential credentialWithLink( String email, String emailLink) => - auth_interop.EmailAuthProviderJsImpl.credentialWithLink(email, emailLink) - as auth_interop.OAuthCredential; + auth_interop.EmailAuthProviderJsImpl.credentialWithLink( + email.toJS, emailLink.toJS) as auth_interop.OAuthCredential; } /// Facebook auth provider. @@ -742,7 +769,7 @@ class EmailAuthProvider class FacebookAuthProvider extends AuthProvider { static String PROVIDER_ID = - auth_interop.FacebookAuthProviderJsImpl.PROVIDER_ID; + auth_interop.FacebookAuthProviderJsImpl.PROVIDER_ID.toDart; /// Creates a new FacebookAuthProvider. factory FacebookAuthProvider() => FacebookAuthProvider.fromJsObject( @@ -756,7 +783,7 @@ class FacebookAuthProvider /// Adds additional OAuth 2.0 scopes that you want to request from the /// authentication provider. FacebookAuthProvider addScope(String scope) => - FacebookAuthProvider.fromJsObject(jsObject.addScope(scope)); + FacebookAuthProvider.fromJsObject(jsObject.addScope(scope.toJS)); /// Sets the OAuth custom parameters to pass in a Facebook OAuth request /// for popup and redirect sign-in operations. @@ -775,7 +802,7 @@ class FacebookAuthProvider /// Creates a credential for Facebook. static auth_interop.OAuthCredential credential(String token) => - auth_interop.FacebookAuthProviderJsImpl.credential(token); + auth_interop.FacebookAuthProviderJsImpl.credential(token.toJS); } /// Github auth provider. @@ -783,7 +810,8 @@ class FacebookAuthProvider /// See: . class GithubAuthProvider extends AuthProvider { - static String PROVIDER_ID = auth_interop.GithubAuthProviderJsImpl.PROVIDER_ID; + static String PROVIDER_ID = + auth_interop.GithubAuthProviderJsImpl.PROVIDER_ID.toDart; /// Creates a new GithubAuthProvider. factory GithubAuthProvider() => @@ -797,7 +825,7 @@ class GithubAuthProvider /// Adds additional OAuth 2.0 scopes that you want to request from the /// authentication provider. GithubAuthProvider addScope(String scope) => - GithubAuthProvider.fromJsObject(jsObject.addScope(scope)); + GithubAuthProvider.fromJsObject(jsObject.addScope(scope.toJS)); /// Sets the OAuth custom parameters to pass in a GitHub OAuth request /// for popup and redirect sign-in operations. @@ -816,7 +844,7 @@ class GithubAuthProvider /// Creates a credential for GitHub. static auth_interop.OAuthCredential credential(String token) => - auth_interop.GithubAuthProviderJsImpl.credential(token); + auth_interop.GithubAuthProviderJsImpl.credential(token.toJS); } /// Google auth provider. @@ -824,7 +852,8 @@ class GithubAuthProvider /// See: . class GoogleAuthProvider extends AuthProvider { - static String PROVIDER_ID = auth_interop.GoogleAuthProviderJsImpl.PROVIDER_ID; + static String PROVIDER_ID = + auth_interop.GoogleAuthProviderJsImpl.PROVIDER_ID.toDart; /// Creates a new GoogleAuthProvider. factory GoogleAuthProvider() => @@ -838,7 +867,7 @@ class GoogleAuthProvider /// Adds additional OAuth 2.0 scopes that you want to request from the /// authentication provider. GoogleAuthProvider addScope(String scope) => - GoogleAuthProvider.fromJsObject(jsObject.addScope(scope)); + GoogleAuthProvider.fromJsObject(jsObject.addScope(scope.toJS)); /// Sets the OAuth custom parameters to pass in a Google OAuth request /// for popup and redirect sign-in operations. @@ -860,7 +889,8 @@ class GoogleAuthProvider /// At least one of [idToken] and [accessToken] is required. static auth_interop.OAuthCredential credential( [String? idToken, String? accessToken]) => - auth_interop.GoogleAuthProviderJsImpl.credential(idToken, accessToken); + auth_interop.GoogleAuthProviderJsImpl.credential( + idToken?.toJS, accessToken?.toJS); } /// OAuth auth provider. @@ -868,8 +898,8 @@ class GoogleAuthProvider /// See: . class OAuthProvider extends AuthProvider { /// Creates a new OAuthProvider. - factory OAuthProvider(String providerId) => - OAuthProvider.fromJsObject(auth_interop.OAuthProviderJsImpl(providerId)); + factory OAuthProvider(String providerId) => OAuthProvider.fromJsObject( + auth_interop.OAuthProviderJsImpl(providerId.toJS)); /// Creates a new OAuthProvider from a [jsObject]. OAuthProvider.fromJsObject(auth_interop.OAuthProviderJsImpl jsObject) @@ -878,7 +908,7 @@ class OAuthProvider extends AuthProvider { /// Adds additional OAuth 2.0 scopes that you want to request from the /// authentication provider. OAuthProvider addScope(String scope) => - OAuthProvider.fromJsObject(jsObject.addScope(scope)); + OAuthProvider.fromJsObject(jsObject.addScope(scope.toJS)); /// Sets the OAuth custom parameters to pass in an OAuth request for popup /// and redirect sign-in operations. For a detailed list, check the reserved @@ -910,7 +940,7 @@ class OAuthProvider extends AuthProvider { class TwitterAuthProvider extends AuthProvider { static String PROVIDER_ID = - auth_interop.TwitterAuthProviderJsImpl.PROVIDER_ID; + auth_interop.TwitterAuthProviderJsImpl.PROVIDER_ID.toDart; /// Creates a new TwitterAuthProvider. factory TwitterAuthProvider() => TwitterAuthProvider.fromJsObject( @@ -936,7 +966,8 @@ class TwitterAuthProvider /// Creates a credential for Twitter. static auth_interop.OAuthCredential credential(String token, String secret) => - auth_interop.TwitterAuthProviderJsImpl.credential(token, secret); + auth_interop.TwitterAuthProviderJsImpl.credential( + token.toJS, secret.toJS); } /// SAML auth provider. @@ -965,7 +996,7 @@ class SAMLAuthProvider class PhoneAuthProvider extends AuthProvider { static String get PROVIDER_ID => - auth_interop.PhoneAuthProviderJsImpl.PROVIDER_ID; + auth_interop.PhoneAuthProviderJsImpl.PROVIDER_ID.toDart; /// Creates a new PhoneAuthProvider with the optional [Auth] instance /// in which sign-ins should occur. @@ -986,8 +1017,9 @@ class PhoneAuthProvider /// For abuse prevention, this method also requires an [ApplicationVerifier]. Future verifyPhoneNumber( dynamic phoneOptions, ApplicationVerifier applicationVerifier) => - handleThenable(jsObject.verifyPhoneNumber( - phoneOptions, applicationVerifier.jsObject)); + jsObject + .verifyPhoneNumber(phoneOptions, applicationVerifier.jsObject) + .toDart as Future; /// Creates a phone auth credential given the verification ID /// from [verifyPhoneNumber] and the [verificationCode] that was sent to the @@ -995,7 +1027,7 @@ class PhoneAuthProvider static auth_interop.PhoneAuthCredentialJsImpl credential( String verificationId, String verificationCode) => auth_interop.PhoneAuthProviderJsImpl.credential( - verificationId, verificationCode); + verificationId.toJS, verificationCode.toJS); } /// A verifier for domain verification and abuse prevention. @@ -1005,7 +1037,7 @@ abstract class ApplicationVerifier< T extends auth_interop.ApplicationVerifierJsImpl> extends JsObjectWrapper { /// Returns the type of application verifier (e.g. 'recaptcha'). - String get type => jsObject.type; + String get type => jsObject.type.toDart; /// Creates a new ApplicationVerifier from a [jsObject]. ApplicationVerifier.fromJsObject(T jsObject) : super.fromJsObject(jsObject); @@ -1013,7 +1045,7 @@ abstract class ApplicationVerifier< /// Executes the verification process. /// Returns a Future containing string for a token that can be used to /// assert the validity of a request. - Future verify() => handleThenable(jsObject.verify()); + Future verify() => jsObject.verify().toDart as Future; } /// reCAPTCHA verifier. @@ -1069,7 +1101,7 @@ class RecaptchaVerifier /// Renders the reCAPTCHA widget on the page. /// Returns a Future that resolves with the reCAPTCHA widget ID. - Future render() => handleThenable(jsObject.render()); + Future render() => jsObject.render().toDart as Future; } /// A result from a phone number sign-in, link, or reauthenticate call. @@ -1080,7 +1112,7 @@ class ConfirmationResult /// Returns the phone number authentication operation's verification ID. /// This can be used along with the verification code to initialize a phone /// auth credential. - String get verificationId => jsObject.verificationId; + String get verificationId => jsObject.verificationId.toDart; /// Creates a new ConfirmationResult from a [jsObject]. ConfirmationResult.fromJsObject( @@ -1089,9 +1121,11 @@ class ConfirmationResult /// Finishes a phone number sign-in, link, or reauthentication, given /// the code that was sent to the user's mobile device. - Future confirm(String verificationCode) => - handleThenable(jsObject.confirm(verificationCode)) - .then(UserCredential.fromJsObject); + Future confirm(String verificationCode) => jsObject + .confirm(verificationCode.toJS) + .toDart + .then((value) => UserCredential.fromJsObject( + value! as auth_interop.UserCredentialJsImpl)); } /// A structure containing a [User], an [OAuthCredential] and [operationType]. @@ -1105,7 +1139,7 @@ class UserCredential User? get user => User.getInstance(jsObject.user); /// Returns the operation type. - String get operationType => jsObject.operationType; + String get operationType => jsObject.operationType.toDart; /// Returns additional user information from a federated identity provider. AdditionalUserInfo? get additionalUserInfo => AdditionalUserInfo.fromJsObject( @@ -1123,16 +1157,16 @@ class UserCredential class AdditionalUserInfo extends JsObjectWrapper { /// Returns the provider id. - String get providerId => jsObject.providerId; + String get providerId => jsObject.providerId.toDart; /// Returns the profile. Map? get profile => dartify(jsObject.profile); /// Returns the user name. - String get username => jsObject.username; + String get username => jsObject.username.toDart; /// Returns whether a user is a new or returning user. - bool get isNewUser => jsObject.isNewUser; + bool get isNewUser => jsObject.isNewUser.toDart; /// Creates a new AdditionalUserInfo from a [jsObject]. AdditionalUserInfo.fromJsObject( diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth_interop.dart b/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth_interop.dart index d91cc1ea042d..191411549434 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth_interop.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/interop/auth_interop.dart @@ -9,21 +9,22 @@ @JS('firebase_auth') library firebase_interop.auth; +import 'dart:js_interop'; + import 'package:firebase_auth_web/src/interop/auth.dart'; import 'package:firebase_core_web/firebase_core_web_interop.dart'; -import 'package:js/js.dart'; @JS() external AuthJsImpl getAuth([AppJsImpl? app]); @JS() -external AuthJsImpl initializeAuth(AppJsImpl app, dynamic debugErrorMap); +external AuthJsImpl initializeAuth(AppJsImpl app, JSAny debugErrorMap); @JS('debugErrorMap') -external Map get debugErrorMap; +external JSAny get debugErrorMap; @JS() -external PromiseJsImpl applyActionCode(AuthJsImpl auth, String oobCode); +external JSPromise applyActionCode(AuthJsImpl auth, JSString oobCode); @JS() external Persistence inMemoryPersistence; @@ -35,31 +36,31 @@ external Persistence browserLocalPersistence; external Persistence indexedDBLocalPersistence; @JS() -external PromiseJsImpl checkActionCode( - AuthJsImpl auth, String oobCode); +// Promise +external JSPromise checkActionCode(AuthJsImpl auth, JSString oobCode); @JS() -external PromiseJsImpl confirmPasswordReset( +external JSPromise confirmPasswordReset( AuthJsImpl auth, - String oobCode, - String newPassword, + JSString oobCode, + JSString newPassword, ); @JS() external void connectAuthEmulator( AuthJsImpl auth, - String origin, + JSString origin, ); @JS() -external PromiseJsImpl setPersistence( - AuthJsImpl auth, Persistence persistence); +external JSPromise setPersistence(AuthJsImpl auth, Persistence persistence); @JS() -external PromiseJsImpl createUserWithEmailAndPassword( +// Promise +external JSPromise createUserWithEmailAndPassword( AuthJsImpl auth, - String email, - String password, + JSString email, + JSString password, ); @JS() @@ -67,173 +68,189 @@ external AdditionalUserInfoJsImpl getAdditionalUserInfo( UserCredentialJsImpl userCredential); @JS() -external PromiseJsImpl deleteUser( +external JSPromise deleteUser( UserJsImpl user, ); @JS() -external PromiseJsImpl fetchSignInMethodsForEmail( - AuthJsImpl auth, String email); +// Promise +external JSPromise fetchSignInMethodsForEmail(AuthJsImpl auth, JSString email); @JS() -external bool isSignInWithEmailLink(String emailLink); +external JSBoolean isSignInWithEmailLink(JSString emailLink); @JS() -external PromiseJsImpl getRedirectResult( +// Promise +external JSPromise getRedirectResult( AuthJsImpl auth, ); @JS() -external PromiseJsImpl sendSignInLinkToEmail( +external JSPromise sendSignInLinkToEmail( AuthJsImpl auth, - String email, [ + JSString email, [ ActionCodeSettings? actionCodeSettings, ]); @JS() -external PromiseJsImpl sendPasswordResetEmail( +external JSPromise sendPasswordResetEmail( AuthJsImpl auth, - String email, [ + JSString email, [ ActionCodeSettings? actionCodeSettings, ]); @JS() -external PromiseJsImpl signInWithCredential( +// Promise +external JSPromise signInWithCredential( AuthJsImpl auth, OAuthCredential credential, ); @JS() -external PromiseJsImpl signInAnonymously(AuthJsImpl auth); +// Promise +external JSPromise signInAnonymously(AuthJsImpl auth); @JS() -external PromiseJsImpl signInWithCustomToken( +// Promise +external JSPromise signInWithCustomToken( AuthJsImpl auth, - String token, + JSString token, ); @JS() -external PromiseJsImpl signInWithEmailAndPassword( +// Promise +external JSPromise signInWithEmailAndPassword( AuthJsImpl auth, - String email, - String password, + JSString email, + JSString password, ); @JS() -external PromiseJsImpl signInWithEmailLink( +// Promise +external JSPromise signInWithEmailLink( AuthJsImpl auth, - String email, - String emailLink, + JSString email, + JSString emailLink, ); @JS() -external PromiseJsImpl signInWithPhoneNumber( +// Promise +external JSPromise signInWithPhoneNumber( AuthJsImpl auth, - String phoneNumber, + JSString phoneNumber, ApplicationVerifierJsImpl applicationVerifier, ); @JS() -external PromiseJsImpl signInWithPopup( +// Promise +external JSPromise signInWithPopup( AuthJsImpl auth, AuthProviderJsImpl provider, ); @JS() -external PromiseJsImpl signInWithRedirect( +external JSPromise signInWithRedirect( AuthJsImpl auth, AuthProviderJsImpl provider, ); @JS() -external PromiseJsImpl verifyPasswordResetCode( +// Promise +external JSPromise verifyPasswordResetCode( AuthJsImpl auth, - String code, + JSString code, ); @JS() -external PromiseJsImpl linkWithCredential( +// Promise +external JSPromise linkWithCredential( UserJsImpl user, OAuthCredential? credential, ); @JS() -external PromiseJsImpl linkWithPhoneNumber( +// Promise +external JSPromise linkWithPhoneNumber( UserJsImpl user, - String phoneNumber, + JSString phoneNumber, ApplicationVerifierJsImpl applicationVerifier, ); @JS() -external PromiseJsImpl linkWithPopup( +// Promise +external JSPromise linkWithPopup( UserJsImpl user, AuthProviderJsImpl provider, ); @JS() -external PromiseJsImpl linkWithRedirect( +external JSPromise linkWithRedirect( UserJsImpl user, AuthProviderJsImpl provider, ); @JS() -external PromiseJsImpl reauthenticateWithCredential( +// Promise +external JSPromise reauthenticateWithCredential( UserJsImpl user, OAuthCredential credential, ); @JS() -external PromiseJsImpl reauthenticateWithPhoneNumber( +// Promise +external JSPromise reauthenticateWithPhoneNumber( UserJsImpl user, - String phoneNumber, + JSString phoneNumber, ApplicationVerifierJsImpl applicationVerifier, ); @JS() -external PromiseJsImpl reauthenticateWithPopup( +// Promise +external JSPromise reauthenticateWithPopup( UserJsImpl user, AuthProviderJsImpl provider, ); @JS() -external PromiseJsImpl reauthenticateWithRedirect( +external JSPromise reauthenticateWithRedirect( UserJsImpl user, AuthProviderJsImpl provider, ); @JS() -external PromiseJsImpl sendEmailVerification([ +external JSPromise sendEmailVerification([ UserJsImpl user, ActionCodeSettings? actionCodeSettings, ]); @JS() -external PromiseJsImpl verifyBeforeUpdateEmail( +external JSPromise verifyBeforeUpdateEmail( UserJsImpl user, - String newEmail, [ + JSString newEmail, [ ActionCodeSettings? actionCodeSettings, ]); @JS() -external PromiseJsImpl unlink(UserJsImpl user, String providerId); +// Promise +external JSPromise unlink(UserJsImpl user, JSString providerId); @JS() -external PromiseJsImpl updateEmail(UserJsImpl user, String newEmail); +external JSPromise updateEmail(UserJsImpl user, JSString newEmail); @JS() -external PromiseJsImpl updatePassword( +external JSPromise updatePassword( UserJsImpl user, - String newPassword, + JSString newPassword, ); @JS() -external PromiseJsImpl updatePhoneNumber( +external JSPromise updatePhoneNumber( UserJsImpl user, OAuthCredential? phoneCredential, ); @JS() -external PromiseJsImpl updateProfile( +external JSPromise updateProfile( UserJsImpl user, UserProfile profile, ); @@ -255,73 +272,87 @@ external MultiFactorResolverJsImpl getMultiFactorResolver( ); @JS('Auth') -abstract class AuthJsImpl { +@staticInterop +abstract class AuthJsImpl {} + +extension AuthJsImplExtension on AuthJsImpl { external AppJsImpl get app; external UserJsImpl get currentUser; - external String get languageCode; - external set languageCode(String? s); + external JSString get languageCode; + external set languageCode(JSString? s); external AuthSettings get settings; - external String? get tenantId; - external set tenantId(String? s); - external Func0 onAuthStateChanged( - dynamic nextOrObserver, [ - Func1? opt_error, - Func0? opt_completed, + external JSString? get tenantId; + external set tenantId(JSString? s); + external JSFunction onAuthStateChanged( + JSFunction nextOrObserver, [ + JSFunction? opt_error, + JSFunction? opt_completed, ]); - external Func0 onIdTokenChanged( - dynamic nextOrObserver, [ - Func1? opt_error, - Func0? opt_completed, + external JSFunction onIdTokenChanged( + JSFunction nextOrObserver, [ + JSFunction? opt_error, + JSFunction? opt_completed, ]); - external PromiseJsImpl signOut(); + external JSPromise signOut(); } @anonymous @JS() -abstract class IdTokenResultImpl { - external String get authTime; - external Object get claims; - external String get expirationTime; - external String get issuedAtTime; - external String get signInProvider; - external String get token; +@staticInterop +abstract class IdTokenResultImpl {} + +extension IdTokenResultImplExtension on IdTokenResultImpl { + external JSString get authTime; + external JSObject get claims; + external JSString get expirationTime; + external JSString get issuedAtTime; + external JSString get signInProvider; + external JSString get token; } @anonymous @JS() -abstract class UserInfoJsImpl { - external String get displayName; - external String get email; - external String get phoneNumber; - external String get photoURL; - external String get providerId; - external String get uid; +@staticInterop +abstract class UserInfoJsImpl {} + +extension UserInfoJsImplExtension on UserInfoJsImpl { + external JSString? get displayName; + external JSString? get email; + external JSString? get phoneNumber; + external JSString? get photoURL; + external JSString get providerId; + external JSString get uid; } /// https://firebase.google.com/docs/reference/js/firebase.User @anonymous @JS() -abstract class UserJsImpl extends UserInfoJsImpl { - external bool get emailVerified; - external bool get isAnonymous; - external List get providerData; - external String get refreshToken; - external String get tenantId; +@staticInterop +abstract class UserJsImpl extends UserInfoJsImpl {} + +extension UserJsImplExtension on UserJsImpl { + external JSBoolean get emailVerified; + external JSBoolean get isAnonymous; + external JSArray get providerData; + external JSString get refreshToken; + external JSString? get tenantId; external UserMetadata get metadata; - external PromiseJsImpl delete(); - external PromiseJsImpl getIdToken([bool? opt_forceRefresh]); - external PromiseJsImpl getIdTokenResult( - [bool? opt_forceRefresh]); - external PromiseJsImpl reload(); - external Object toJSON(); + external JSPromise delete(); + external JSPromise getIdToken([JSBoolean? opt_forceRefresh]); + external JSPromise getIdTokenResult([JSBoolean? opt_forceRefresh]); + external JSPromise reload(); + external JSObject toJSON(); } /// An enumeration of the possible persistence mechanism types. /// /// See: @JS('Persistence') -class Persistence { - external String get type; +@staticInterop +class Persistence {} + +extension PersistenceExtension on Persistence { + external JSString get type; } /// Interface that represents the credentials returned by an auth provider. @@ -330,15 +361,18 @@ class Persistence { /// /// See . @JS('AuthCredential') -abstract class AuthCredential { +@staticInterop +abstract class AuthCredential {} + +extension AuthCredentialExtension on AuthCredential { /// The authentication provider ID for the credential. For example, /// 'facebook.com', or 'google.com'. - external String get providerId; + external JSString get providerId; /// The authentication sign in method for the credential. For example, /// 'password', or 'emailLink'. This corresponds to the sign-in method /// identifier as returned in firebase.auth.Auth.fetchSignInMethodsForEmail. - external String get signInMethod; + external JSString get signInMethod; } /// Interface that represents the OAuth credentials returned by an OAuth @@ -347,170 +381,227 @@ abstract class AuthCredential { /// /// See: . @JS() +@staticInterop @anonymous -abstract class OAuthCredential extends AuthCredential { +abstract class OAuthCredential extends AuthCredential {} + +extension OAuthCredentialExtension on OAuthCredential { /// The OAuth access token associated with the credential if it belongs to /// an OAuth provider, such as facebook.com, twitter.com, etc. - external String get accessToken; + external JSString get accessToken; /// The OAuth ID token associated with the credential if it belongs to an /// OIDC provider, such as google.com. - external String get idToken; + external JSString get idToken; /// The OAuth access token secret associated with the credential if it /// belongs to an OAuth 1.0 provider, such as twitter.com. - external String get secret; + external JSString get secret; } /// Defines the options for initializing an firebase.auth.OAuthCredential. /// For ID tokens with nonce claim, the raw nonce has to also be provided. @JS() +@staticInterop @anonymous class OAuthCredentialOptions { + external factory OAuthCredentialOptions({ + JSString? accessToken, + JSString? idToken, + JSString? rawNonce, + }); +} + +extension OAuthCredentialOptionsExtension on OAuthCredentialOptions { /// The OAuth access token used to initialize the OAuthCredential. - external String get accessToken; - external set accessToken(String a); + external JSString get accessToken; + external set accessToken(JSString a); /// The OAuth ID token used to initialize the OAuthCredential. - external String get idToken; - external set idToken(String i); + external JSString get idToken; + external set idToken(JSString i); /// The raw nonce associated with the ID token. It is required when an ID token with a nonce field is provided. /// The SHA-256 hash of the raw nonce must match the nonce field in the ID token. - external String get rawNonce; - external set rawNonce(String r); - external factory OAuthCredentialOptions({ - String? accessToken, - String? idToken, - String? rawNonce, - }); + external JSString get rawNonce; + external set rawNonce(JSString r); } @JS('AuthProvider') +@staticInterop @anonymous -abstract class AuthProviderJsImpl { - external String get providerId; +abstract class AuthProviderJsImpl {} + +extension AuthProviderJsImplExtension on AuthProviderJsImpl { + external JSString get providerId; } @JS('EmailAuthProvider') -class EmailAuthProviderJsImpl extends AuthProviderJsImpl { +@staticInterop +abstract class EmailAuthProviderJsImpl extends AuthProviderJsImpl { external factory EmailAuthProviderJsImpl(); - external static String get PROVIDER_ID; - external static AuthCredential credential(String email, String password); + + external static JSString get PROVIDER_ID; + external static AuthCredential credential(JSString email, JSString password); external static AuthCredential credentialWithLink( - String email, - String emailLink, + JSString email, + JSString emailLink, ); } @JS('FacebookAuthProvider') -class FacebookAuthProviderJsImpl extends AuthProviderJsImpl { +@staticInterop +abstract class FacebookAuthProviderJsImpl extends AuthProviderJsImpl { external factory FacebookAuthProviderJsImpl(); - external static String get PROVIDER_ID; - external FacebookAuthProviderJsImpl addScope(String scope); + + external static JSString get PROVIDER_ID; + external static OAuthCredential credential(JSString token); +} + +extension FacebookAuthProviderJsImplExtension on FacebookAuthProviderJsImpl { + external FacebookAuthProviderJsImpl addScope(JSString scope); external FacebookAuthProviderJsImpl setCustomParameters( - dynamic customOAuthParameters, + JSAny customOAuthParameters, ); - external static OAuthCredential credential(String token); } @JS('GithubAuthProvider') -class GithubAuthProviderJsImpl extends AuthProviderJsImpl { +@staticInterop +abstract class GithubAuthProviderJsImpl extends AuthProviderJsImpl { external factory GithubAuthProviderJsImpl(); - external static String get PROVIDER_ID; - external GithubAuthProviderJsImpl addScope(String scope); + + external static JSString get PROVIDER_ID; + external static OAuthCredential credential(JSString token); +} + +extension GithubAuthProviderJsImplExtension on GithubAuthProviderJsImpl { + external GithubAuthProviderJsImpl addScope(JSString scope); external GithubAuthProviderJsImpl setCustomParameters( - dynamic customOAuthParameters, + JSAny customOAuthParameters, ); - external static OAuthCredential credential(String token); } @JS('GoogleAuthProvider') -class GoogleAuthProviderJsImpl extends AuthProviderJsImpl { +@staticInterop +abstract class GoogleAuthProviderJsImpl extends AuthProviderJsImpl { external factory GoogleAuthProviderJsImpl(); - external static String get PROVIDER_ID; - external GoogleAuthProviderJsImpl addScope(String scope); + + external static JSString get PROVIDER_ID; + external static OAuthCredential credential( + [JSString? idToken, JSString? accessToken]); +} + +extension GoogleAuthProviderJsImplExtension on GoogleAuthProviderJsImpl { + external GoogleAuthProviderJsImpl addScope(JSString scope); external GoogleAuthProviderJsImpl setCustomParameters( - dynamic customOAuthParameters, + JSAny customOAuthParameters, ); - external static OAuthCredential credential( - [String? idToken, String? accessToken]); } @JS('OAuthProvider') +@staticInterop class OAuthProviderJsImpl extends AuthProviderJsImpl { - external factory OAuthProviderJsImpl(String providerId); - external OAuthProviderJsImpl addScope(String scope); - external OAuthProviderJsImpl setCustomParameters( - dynamic customOAuthParameters, - ); - external OAuthCredential credential(OAuthCredentialOptions credentialOptions); + external factory OAuthProviderJsImpl(JSString providerId); + external static OAuthCredential? credentialFromResult( UserCredentialJsImpl userCredential, ); } +extension OAuthProviderJsImplExtension on OAuthProviderJsImpl { + external OAuthProviderJsImpl addScope(JSString scope); + external OAuthProviderJsImpl setCustomParameters( + JSAny customOAuthParameters, + ); + external OAuthCredential credential(OAuthCredentialOptions credentialOptions); +} + @JS('TwitterAuthProvider') +@staticInterop class TwitterAuthProviderJsImpl extends AuthProviderJsImpl { external factory TwitterAuthProviderJsImpl(); - external static String get PROVIDER_ID; + external static JSString get PROVIDER_ID; + + external static OAuthCredential credential(JSString token, JSString secret); +} + +extension TwitterAuthProviderJsImplExtension on TwitterAuthProviderJsImpl { external TwitterAuthProviderJsImpl setCustomParameters( - dynamic customOAuthParameters, + JSAny customOAuthParameters, ); - external static OAuthCredential credential(String token, String secret); } @JS('PhoneAuthProvider') +@staticInterop class PhoneAuthProviderJsImpl extends AuthProviderJsImpl { external factory PhoneAuthProviderJsImpl([AuthJsImpl? auth]); - external static String get PROVIDER_ID; - external PromiseJsImpl verifyPhoneNumber( - dynamic /* PhoneInfoOptions | string */ phoneOptions, - ApplicationVerifierJsImpl applicationVerifier, - ); + external static JSString get PROVIDER_ID; + external static PhoneAuthCredentialJsImpl credential( - String verificationId, - String verificationCode, + JSString verificationId, + JSString verificationCode, + ); +} + +extension PhoneAuthProviderJsImplExtension on PhoneAuthProviderJsImpl { + external JSPromise verifyPhoneNumber( + JSAny /* PhoneInfoOptions | string */ phoneOptions, + ApplicationVerifierJsImpl applicationVerifier, ); } @JS('SAMLAuthProvider') +@staticInterop class SAMLAuthProviderJsImpl extends AuthProviderJsImpl { external factory SAMLAuthProviderJsImpl(String providerId); + external static OAuthCredential? credentialFromResult( UserCredentialJsImpl userCredential, ); } @JS('ApplicationVerifier') -abstract class ApplicationVerifierJsImpl { - external String get type; - external PromiseJsImpl verify(); +@staticInterop +abstract class ApplicationVerifierJsImpl {} + +extension ApplicationVerifierJsImplExtension on ApplicationVerifierJsImpl { + external JSString get type; + external JSPromise verify(); } @JS('RecaptchaVerifier') +@staticInterop class RecaptchaVerifierJsImpl extends ApplicationVerifierJsImpl { external factory RecaptchaVerifierJsImpl( AuthJsImpl authExtern, - containerOrId, - Object parameters, + JSAny containerOrId, + JSObject parameters, ); +} + +extension RecaptchaVerifierJsImplExtension on RecaptchaVerifierJsImpl { external void clear(); - external PromiseJsImpl render(); + external JSPromise render(); } @JS('ConfirmationResult') -abstract class ConfirmationResultJsImpl { - external String get verificationId; - external PromiseJsImpl confirm(String verificationCode); +@staticInterop +abstract class ConfirmationResultJsImpl {} + +extension ConfirmationResultJsImplExtension on ConfirmationResultJsImpl { + external JSString get verificationId; + external JSPromise confirm(JSString verificationCode); } /// A response from [Auth.checkActionCode]. /// /// See: . @JS() -abstract class ActionCodeInfo { +@staticInterop +abstract class ActionCodeInfo {} + +extension ActionCodeInfoExtension on ActionCodeInfo { external ActionCodeData get data; } @@ -518,26 +609,32 @@ abstract class ActionCodeInfo { /// /// See: . @JS() -abstract class UserMetadata { +@staticInterop +abstract class UserMetadata {} + +extension UserMetadataExtension on UserMetadata { /// The date the user was created, formatted as a UTC string. /// For example, 'Fri, 22 Sep 2017 01:49:58 GMT'. - external String? get creationTime; + external JSString? get creationTime; /// The date the user last signed in, formatted as a UTC string. /// For example, 'Fri, 22 Sep 2017 01:49:58 GMT'. - external String? get lastSignInTime; + external JSString? get lastSignInTime; } /// A structure for [User]'s user profile. @JS() +@staticInterop @anonymous class UserProfile { - external String get displayName; - external set displayName(String s); - external String get photoURL; - external set photoURL(String s); + external factory UserProfile({JSString? displayName, JSString? photoURL}); +} - external factory UserProfile({String? displayName, String? photoURL}); +extension UserProfileExtension on UserProfile { + external JSString get displayName; + external set displayName(JSString s); + external JSString get photoURL; + external set photoURL(JSString s); } @JS() @@ -548,19 +645,19 @@ abstract class AuthError {} /// /// See: . extension AuthErrorExtension on AuthError { - external String get code; - external set code(String s); - external String get message; - external set message(String s); - external String get email; - external set email(String s); + external JSString get code; + external set code(JSString s); + external JSString get message; + external set message(JSString s); + external JSString get email; + external set email(JSString s); external AuthCredential get credential; external set credential(AuthCredential c); - external String get tenantId; - external set tenantId(String s); - external String get phoneNumber; - external set phoneNumber(String s); - external Object get customData; + external JSString get tenantId; + external set tenantId(JSString s); + external JSString get phoneNumber; + external set phoneNumber(JSString s); + external JSObject get customData; } @JS() @@ -568,17 +665,20 @@ extension AuthErrorExtension on AuthError { class AuthErrorCustomData {} extension AuthErrorCustomDataExtension on AuthErrorCustomData { - external String get appName; - external String? get email; - external String? get phoneNumber; - external String? get tenantId; + external JSString get appName; + external JSString? get email; + external JSString? get phoneNumber; + external JSString? get tenantId; } @JS() +@staticInterop @anonymous -class ActionCodeData { - external String get email; - external String get previousEmail; +class ActionCodeData {} + +extension ActionCodeDataExtension on ActionCodeData { + external JSString get email; + external JSString get previousEmail; } /// This is the interface that defines the required continue/state URL with @@ -605,37 +705,45 @@ class ActionCodeData { /// /// See: @JS() +@staticInterop @anonymous class ActionCodeSettings { - external String get url; - external set url(String s); - external IosSettings get iOS; - external set iOS(IosSettings i); - external AndroidSettings get android; - external set android(AndroidSettings a); - external bool get handleCodeInApp; - external set handleCodeInApp(bool b); - external String get dynamicLinkDomain; - external set dynamicLinkDomain(String d); external factory ActionCodeSettings({ - String? url, + JSString? url, IosSettings? iOS, AndroidSettings? android, - bool? handleCodeInApp, - String? dynamicLinkDomain, + JSBoolean? handleCodeInApp, + JSString? dynamicLinkDomain, }); } +extension ActionCodeSettingsExtension on ActionCodeSettings { + external JSString get url; + external set url(JSString s); + external IosSettings get iOS; + external set iOS(IosSettings i); + external AndroidSettings get android; + external set android(AndroidSettings a); + external JSBoolean get handleCodeInApp; + external set handleCodeInApp(JSBoolean b); + external JSString get dynamicLinkDomain; + external set dynamicLinkDomain(JSString d); +} + /// The iOS settings. /// /// Sets the iOS [bundleId]. /// This will try to open the link in an iOS app if it is installed. @JS() +@staticInterop @anonymous class IosSettings { - external String get bundleId; - external set bundleId(String s); - external factory IosSettings({String? bundleId}); + external factory IosSettings({JSString? bundleId}); +} + +extension IosSettingsExtension on IosSettings { + external JSString get bundleId; + external set bundleId(JSString s); } /// The Android settings. @@ -652,160 +760,211 @@ class IosSettings { /// If [minimumVersion] is specified, and an older version of the app /// is installed, the user is taken to the Play Store to upgrade the app. @JS() +@staticInterop @anonymous class AndroidSettings { - external String get packageName; - external set packageName(String s); - external String get minimumVersion; - external set minimumVersion(String s); - external bool get installApp; - external set installApp(bool b); external factory AndroidSettings({ - String? packageName, - String? minimumVersion, - bool? installApp, + JSString? packageName, + JSString? minimumVersion, + JSBoolean? installApp, }); } +extension AndroidSettingsExtension on AndroidSettings { + external JSString get packageName; + external set packageName(JSString s); + external JSString get minimumVersion; + external set minimumVersion(JSString s); + external JSBoolean get installApp; + external set installApp(JSBoolean b); +} + /// https://firebase.google.com/docs/reference/js/auth.usercredential @JS() +@staticInterop @anonymous -class UserCredentialJsImpl { +class UserCredentialJsImpl {} + +extension UserCredentialJsImplExtension on UserCredentialJsImpl { external UserJsImpl get user; - external String get operationType; + external JSString get operationType; external AdditionalUserInfoJsImpl get additionalUserInfo; } /// https://firebase.google.com/docs/reference/js/firebase.auth#.AdditionalUserInfo @JS() +@staticInterop @anonymous -class AdditionalUserInfoJsImpl { - external String get providerId; - external Object get profile; - external String get username; - external bool get isNewUser; +class AdditionalUserInfoJsImpl {} + +extension AdditionalUserInfoJsImplExtension on AdditionalUserInfoJsImpl { + external JSString get providerId; + external JSObject get profile; + external JSString get username; + external JSBoolean get isNewUser; } /// https://firebase.google.com/docs/reference/js/firebase.auth#.AdditionalUserInfo @JS() +@staticInterop @anonymous class AuthSettings { - external bool get appVerificationDisabledForTesting; - external set appVerificationDisabledForTesting(bool? b); - // external factory AuthSettings({bool appVerificationDisabledForTesting}); + // external factory AuthSettings({JSBoolean appVerificationDisabledForTesting}); +} + +extension AuthSettingsExtension on AuthSettings { + external JSBoolean get appVerificationDisabledForTesting; + external set appVerificationDisabledForTesting(JSBoolean? b); } -external dynamic get browserPopupRedirectResolver; +@JS() +@staticInterop +external JSAny get browserPopupRedirectResolver; /// https://firebase.google.com/docs/reference/js/auth.multifactoruser.md#multifactoruser_interface @JS() +@staticInterop @anonymous -class MultiFactorUserJsImpl { - external List get enrolledFactors; - external PromiseJsImpl enroll( - MultiFactorAssertionJsImpl assertion, String? displayName); - external PromiseJsImpl getSession(); - external PromiseJsImpl unenroll( - dynamic /* MultiFactorInfo | string */ option); +class MultiFactorUserJsImpl {} + +extension MultiFactorUserJsImplExtension on MultiFactorUserJsImpl { + external JSArray get enrolledFactors; + external JSPromise enroll( + MultiFactorAssertionJsImpl assertion, JSString? displayName); + external JSPromise getSession(); + external JSPromise unenroll(JSAny /* MultiFactorInfo | string */ option); } /// https://firebase.google.com/docs/reference/js/auth.multifactorinfo @JS() +@staticInterop @anonymous -class MultiFactorInfoJsImpl { - external String? get displayName; - external String get enrollmentTime; - external String get factorId; - external String get uid; +class MultiFactorInfoJsImpl {} + +extension MultiFactorInfoJsImplExtension on MultiFactorInfoJsImpl { + external JSString? get displayName; + external JSString get enrollmentTime; + external JSString get factorId; + external JSString get uid; } /// https://firebase.google.com/docs/reference/js/auth.multifactorassertion @JS() +@staticInterop @anonymous -class MultiFactorAssertionJsImpl { - external String get factorId; +class MultiFactorAssertionJsImpl {} + +extension MultiFactorAssertionJsImplExtension on MultiFactorAssertionJsImpl { + external JSString get factorId; } /// https://firebase.google.com/docs/reference/js/auth.multifactorresolver @JS() +@staticInterop @anonymous -class MultiFactorResolverJsImpl { - external List get hints; +class MultiFactorResolverJsImpl {} + +extension MultiFactorResolverJsImplExtension on MultiFactorResolverJsImpl { + external JSArray get hints; external MultiFactorSessionJsImpl get session; - external PromiseJsImpl resolveSignIn( - MultiFactorAssertionJsImpl assertion); + external JSPromise resolveSignIn(MultiFactorAssertionJsImpl assertion); } /// https://firebase.google.com/docs/reference/js/auth.multifactorresolver @JS() +@staticInterop @anonymous class MultiFactorSessionJsImpl {} /// https://firebase.google.com/docs/reference/js/auth.phonemultifactorinfo @JS('PhoneMultiFactorInfo') -class PhoneMultiFactorInfoJsImpl extends MultiFactorInfoJsImpl { - external String get phoneNumber; +@staticInterop +class PhoneMultiFactorInfoJsImpl extends MultiFactorInfoJsImpl {} + +extension PhoneMultiFactorInfoJsImplExtension on PhoneMultiFactorInfoJsImpl { + external JSString get phoneNumber; } /// https://firebase.google.com/docs/reference/js/auth.totpmultifactorinfo @JS('TotpMultiFactorInfo') +@staticInterop class TotpMultiFactorInfoJsImpl extends MultiFactorInfoJsImpl {} /// https://firebase.google.com/docs/reference/js/auth.phonemultifactorenrollinfooptions @JS() +@staticInterop @anonymous -class PhoneMultiFactorEnrollInfoOptionsJsImpl { - external String get phoneNumber; +class PhoneMultiFactorEnrollInfoOptionsJsImpl {} + +extension PhoneMultiFactorEnrollInfoOptionsJsImplExtension + on PhoneMultiFactorEnrollInfoOptionsJsImpl { + external JSString get phoneNumber; external MultiFactorSessionJsImpl? get session; } /// https://firebase.google.com/docs/reference/js/auth.phonemultifactorgenerator @JS('PhoneMultiFactorGenerator') +@staticInterop class PhoneMultiFactorGeneratorJsImpl { - external static String get FACTOR_ID; + external static JSString get FACTOR_ID; external static PhoneMultiFactorAssertionJsImpl? assertion( PhoneAuthCredentialJsImpl credential); } +extension PhoneMultiFactorGeneratorJsImplExtension + on PhoneMultiFactorGeneratorJsImpl {} + /// https://firebase.google.com/docs/reference/js/auth.totpsecret @JS('TotpSecret') -class TotpSecretJsImpl { - external num get codeIntervalSeconds; - external num get codeLength; - external String get enrollmentCompletionDeadline; - external String get hashingAlgorithm; - external String get secretKey; +@staticInterop +class TotpSecretJsImpl {} - external String generateQrCodeUrl(String? accountName, String? issuer); +extension TotpSecretJsImplExtension on TotpSecretJsImpl { + external JSNumber get codeIntervalSeconds; + external JSNumber get codeLength; + external JSString get enrollmentCompletionDeadline; + external JSString get hashingAlgorithm; + external JSString get secretKey; + + external JSString generateQrCodeUrl(JSString? accountName, JSString? issuer); } /// https://firebase.google.com/docs/reference/js/auth.totpmultifactorgenerator @JS('TotpMultiFactorGenerator') +@staticInterop class TotpMultiFactorGeneratorJsImpl { - external static String get FACTOR_ID; + external static JSString get FACTOR_ID; external static TotpMultiFactorAssertionJsImpl? assertionForEnrollment( - TotpSecretJsImpl secret, String oneTimePassword); + TotpSecretJsImpl secret, JSString oneTimePassword); external static TotpMultiFactorAssertionJsImpl? assertionForSignIn( - String enrollmentId, String oneTimePassword); - external static PromiseJsImpl generateSecret( - MultiFactorSessionJsImpl session); + JSString enrollmentId, JSString oneTimePassword); + external static JSPromise generateSecret(MultiFactorSessionJsImpl session); } +extension TotpMultiFactorGeneratorJsImplExtension + on TotpMultiFactorGeneratorJsImpl {} + /// https://firebase.google.com/docs/reference/js/auth.phonemultifactorassertion @JS() +@staticInterop @anonymous class PhoneMultiFactorAssertionJsImpl extends MultiFactorAssertionJsImpl {} /// https://firebase.google.com/docs/reference/js/auth.totpmultifactorassertion @JS() +@staticInterop @anonymous class TotpMultiFactorAssertionJsImpl extends MultiFactorAssertionJsImpl {} /// https://firebase.google.com/docs/reference/js/auth.phoneauthcredential @JS() +@staticInterop @anonymous class PhoneAuthCredentialJsImpl extends AuthCredential { external static PhoneAuthCredentialJsImpl fromJSON( - dynamic /*object | string*/ json); - external Object toJSON(); + JSAny /*object | string*/ json); +} + +extension PhoneAuthCredentialJsImplExtension on PhoneAuthCredentialJsImpl { + external JSObject toJSON(); } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/interop/multi_factor.dart b/packages/firebase_auth/firebase_auth_web/lib/src/interop/multi_factor.dart index d87c0486aede..00061da8f23f 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/interop/multi_factor.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/interop/multi_factor.dart @@ -6,6 +6,8 @@ // ignore_for_file: non_constant_identifier_names // ignore_for_file: public_member_api_docs +import 'dart:js_interop'; + import 'package:firebase_core_web/firebase_core_web_interop.dart' hide jsify, dartify; import 'package:http_parser/http_parser.dart'; @@ -42,15 +44,17 @@ class MultiFactorUser : super.fromJsObject(jsObject); /// Returns a list of the user's enrolled second factors. - List get enrolledFactors => - jsObject.enrolledFactors.map(fromJsMultiFactorInfo).toList(); + List get enrolledFactors => jsObject.enrolledFactors.toDart + .map((value) => + fromJsMultiFactorInfo(value! as auth.MultiFactorInfoJsImpl)) + .toList(); /// Returns the session identifier for a second factor enrollment operation. /// /// This is used to identify the user trying to enroll a second factor. - Future get session => - handleThenable(jsObject.getSession()) - .then(MultiFactorSession.fromJsObject); + Future get session => jsObject.getSession().toDart.then( + (value) => MultiFactorSession.fromJsObject( + value! as auth_interop.MultiFactorSessionJsImpl)); /// Enrolls a second factor as identified by the [MultiFactorAssertion] for the user. /// @@ -60,7 +64,7 @@ class MultiFactorUser /// existing Firebase sessions (refresh tokens) are revoked. When a new factor is enrolled, /// an email notification is sent to the user’s email. Future enroll(MultiFactorAssertion assertion, String? displayName) { - return handleThenable(jsObject.enroll(assertion.jsObject, displayName)); + return jsObject.enroll(assertion.jsObject, displayName?.toJS).toDart; } /// Unenrolls the specified second factor. @@ -72,7 +76,7 @@ class MultiFactorUser /// Recent re-authentication is required for this operation to succeed. /// When an existing factor is unenrolled, an email notification is sent to the user’s email. Future unenroll(String multiFactorInfoId) { - return handleThenable(jsObject.unenroll(multiFactorInfoId)); + return jsObject.unenroll(multiFactorInfoId.toJS).toDart; } } @@ -82,16 +86,16 @@ class MultiFactorInfo MultiFactorInfo.fromJsObject(T jsObject) : super.fromJsObject(jsObject); /// The user friendly name of the current second factor. - String? get displayName => jsObject.displayName; + String? get displayName => jsObject.displayName?.toDart; /// The enrollment date of the second factor formatted as a UTC string. - String get enrollmentTime => jsObject.enrollmentTime; + String get enrollmentTime => jsObject.enrollmentTime.toDart; /// The identifier of the second factor. - String get factorId => jsObject.factorId; + String get factorId => jsObject.factorId.toDart; /// The multi-factor enrollment ID. - String get uid => jsObject.uid; + String get uid => jsObject.uid.toDart; } class PhoneMultiFactorInfo @@ -101,7 +105,7 @@ class PhoneMultiFactorInfo : super.fromJsObject(jsObject); /// The user friendly name of the current second factor. - String get phoneNumber => jsObject.phoneNumber; + String get phoneNumber => jsObject.phoneNumber.toDart; } class TotpMultiFactorInfo @@ -123,7 +127,7 @@ class MultiFactorAssertion extends JsObjectWrapper { MultiFactorAssertion.fromJsObject(T jsObject) : super.fromJsObject(jsObject); - String get factorId => jsObject.factorId; + String get factorId => jsObject.factorId.toDart; } /// https://firebase.google.com/docs/reference/js/auth.multifactorsession.md#multifactorsession_interface @@ -140,23 +144,25 @@ class MultiFactorResolver MultiFactorResolver.fromJsObject(auth.MultiFactorResolverJsImpl jsObject) : super.fromJsObject(jsObject); - List get hints => - jsObject.hints.map(fromJsMultiFactorInfo).toList(); + List get hints => jsObject.hints.toDart + .map((value) => + fromJsMultiFactorInfo(value! as auth.MultiFactorInfoJsImpl)) + .toList(); MultiFactorSession get session => MultiFactorSession.fromJsObject(jsObject.session); Future resolveSignIn(MultiFactorAssertion assertion) { - return handleThenable(jsObject.resolveSignIn(assertion.jsObject)) - .then(auth.UserCredential.fromJsObject); + return jsObject.resolveSignIn(assertion.jsObject).toDart.then((value) => + auth.UserCredential.fromJsObject(value! as auth.UserCredentialJsImpl)); } } MultiFactorInfo fromJsMultiFactorInfo(auth.MultiFactorInfoJsImpl e) { - if (e.factorId == 'phone') { + if (e.factorId.toDart == 'phone') { return PhoneMultiFactorInfo.fromJsObject( e as auth_interop.PhoneMultiFactorInfoJsImpl); - } else if (e.factorId == 'totp') { + } else if (e.factorId.toDart == 'totp') { return TotpMultiFactorInfo.fromJsObject( e as auth_interop.TotpMultiFactorInfoJsImpl); } else { @@ -190,15 +196,15 @@ class TotpSecret extends JsObjectWrapper { TotpSecret.fromJsObject(auth_interop.TotpSecretJsImpl jsObject) : super.fromJsObject(jsObject); - int get codeInterval => jsObject.codeIntervalSeconds.toInt(); - int get codeLength => jsObject.codeLength.toInt(); + int get codeInterval => jsObject.codeIntervalSeconds.toDartInt; + int get codeLength => jsObject.codeLength.toDartInt; DateTime get enrollmentCompletionDeadline => - parseHttpDate(jsObject.enrollmentCompletionDeadline); - String get hashingAlgorithm => jsObject.hashingAlgorithm; - String get secretKey => jsObject.secretKey; + parseHttpDate(jsObject.enrollmentCompletionDeadline.toDart); + String get hashingAlgorithm => jsObject.hashingAlgorithm.toDart; + String get secretKey => jsObject.secretKey.toDart; String generateQrCodeUrl(String? accountName, String? issuer) { - return jsObject.generateQrCodeUrl(accountName, issuer); + return jsObject.generateQrCodeUrl(accountName?.toJS, issuer?.toJS).toDart; } } @@ -212,7 +218,7 @@ class TotpMultiFactorGenerator String enrollmentId, String oneTimePassword) { return TotpMultiFactorAssertion.fromJsObject( auth_interop.TotpMultiFactorGeneratorJsImpl.assertionForSignIn( - enrollmentId, oneTimePassword)!, + enrollmentId.toJS, oneTimePassword.toJS)!, ); } @@ -221,15 +227,16 @@ class TotpMultiFactorGenerator return TotpMultiFactorAssertion.fromJsObject( auth_interop.TotpMultiFactorGeneratorJsImpl.assertionForEnrollment( secret.jsObject, - oneTimePassword, + oneTimePassword.toJS, )!, ); } static Future generateSecret(MultiFactorSession session) { - return handleThenable( - auth_interop.TotpMultiFactorGeneratorJsImpl.generateSecret( - session.jsObject), - ).then(TotpSecret.fromJsObject); + return auth_interop.TotpMultiFactorGeneratorJsImpl.generateSecret( + session.jsObject) + .toDart + .then((value) => + TotpSecret.fromJsObject(value! as auth_interop.TotpSecretJsImpl)); } } diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/interop/window_interop.dart b/packages/firebase_auth/firebase_auth_web/lib/src/interop/window_interop.dart index 2d490ab08b0c..817fce9c4e2e 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/interop/window_interop.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/interop/window_interop.dart @@ -5,7 +5,8 @@ @JS() library window_interop; -import 'package:js/js.dart'; +import 'dart:js_interop'; @JS('Error') +@staticInterop external Object get errorConstructor; diff --git a/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart b/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart index 6ab93987812a..91d1245bbac2 100644 --- a/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart +++ b/packages/firebase_auth/firebase_auth_web/lib/src/utils/web_utils.dart @@ -4,38 +4,24 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:io'; +import 'dart:js_interop'; import 'package:firebase_auth_platform_interface/firebase_auth_platform_interface.dart'; import 'package:firebase_auth_web/firebase_auth_web.dart'; import 'package:firebase_auth_web/src/firebase_auth_web_multi_factor.dart'; import 'package:firebase_core_web/firebase_core_web_interop.dart' as core_interop; -import 'package:js/js_util.dart'; +import 'package:firebase_core_web/firebase_core_web_interop.dart'; import '../interop/auth.dart' as auth_interop; import '../interop/multi_factor.dart' as multi_factor_interop; -import '../interop/window_interop.dart' as window_interop; -/// Workaround test to check whether `e` is practically a FirebaseError. -/// -/// Ideally we'd check whether `e instanceof FirebaseError` however -/// there are two definitions of `FirebaseError` in deployed apps, one from -/// `firebase-auth.js` (which is usually minified) and one from -/// `firebase-app.js`. -/// -/// Because they are not the same, the instanceof check fails. Instead, we test -/// that it is a window.Error (since that's the base class of FirebaseError) and -/// we check that it defines "customData" property which is on the AuthError but not the FirebaseError it extends -bool _isFirebaseAuthError(Object e) => - instanceof(e, window_interop.errorConstructor) && - hasProperty(e, 'customData'); - -bool _hasFirebaseAuthErrorCodeAndMessage(Object e) { - if (_isFirebaseAuthError(e)) { - String? code = getProperty(e, 'code'); - String? message = getProperty(e, 'message'); - if (code == null || !code.startsWith('auth/')) return false; - if (message == null || !message.contains('Firebase')) return false; +bool _hasFirebaseAuthErrorCodeAndMessage(JSError e) { + if (e.name == 'FirebaseError') { + String code = e.code ?? ''; + String message = e.message ?? ''; + if (code.startsWith('auth/')) return false; + if (message.contains('Firebase')) return false; return true; } else { return false; @@ -47,9 +33,10 @@ bool _hasFirebaseAuthErrorCodeAndMessage(Object e) { /// The firebase-dart wrapper exposes a [core_interop.FirebaseError], allowing us to /// use the code and message and convert it into an expected [FirebaseAuthException]. FirebaseAuthException getFirebaseAuthException( - Object exception, [ + Object objectException, [ auth_interop.Auth? auth, ]) { + final exception = objectException as JSError; if (!_hasFirebaseAuthErrorCodeAndMessage(exception)) { return FirebaseAuthException( code: 'unknown', @@ -58,14 +45,13 @@ FirebaseAuthException getFirebaseAuthException( } auth_interop.AuthError firebaseError = exception as auth_interop.AuthError; - String code = firebaseError.code.replaceFirst('auth/', ''); - String message = firebaseError.message + String code = firebaseError.code.toDart.replaceFirst('auth/', ''); + String message = firebaseError.message.toDart .replaceFirst(' (${firebaseError.code}).', '') .replaceFirst('Firebase: ', ''); // "customData" - see Firebase AuthError docs: https://firebase.google.com/docs/reference/js/auth.autherror - final customData = - getProperty(exception, 'customData') as auth_interop.AuthErrorCustomData; + final customData = exception.customData as auth_interop.AuthErrorCustomData; if (code == 'multi-factor-auth-required') { final _auth = auth; @@ -78,15 +64,15 @@ FirebaseAuthException getFirebaseAuthException( } final resolverWeb = multi_factor_interop.getMultiFactorResolver( _auth, - exception, + exception as dynamic, ); return FirebaseAuthMultiFactorExceptionPlatform( code: code, message: message, - email: customData.email, - phoneNumber: customData.phoneNumber, - tenantId: customData.tenantId, + email: customData.email?.toDart, + phoneNumber: customData.phoneNumber?.toDart, + tenantId: customData.tenantId?.toDart, resolver: MultiFactorResolverWeb( resolverWeb.hints.map(fromInteropMultiFactorInfo).toList(), MultiFactorSessionWeb('web', resolverWeb.session), @@ -100,9 +86,9 @@ FirebaseAuthException getFirebaseAuthException( return FirebaseAuthException( code: code, message: message, - email: customData.email, - phoneNumber: customData.phoneNumber, - tenantId: customData.tenantId, + email: customData.email?.toDart, + phoneNumber: customData.phoneNumber?.toDart, + tenantId: customData.tenantId?.toDart, ); } @@ -146,8 +132,8 @@ ActionCodeInfo? convertWebActionCodeInfo( return ActionCodeInfo( operation: ActionCodeInfoOperation.passwordReset, data: ActionCodeInfoData( - email: webActionCodeInfo.data.email, - previousEmail: webActionCodeInfo.data.previousEmail, + email: webActionCodeInfo.data.email.toDart, + previousEmail: webActionCodeInfo.data.previousEmail.toDart, ), ); } @@ -198,14 +184,14 @@ auth_interop.ActionCodeSettings? convertPlatformActionCodeSettings( if (actionCodeSettings.dynamicLinkDomain != null) { webActionCodeSettings = auth_interop.ActionCodeSettings( - url: actionCodeSettings.url, - handleCodeInApp: actionCodeSettings.handleCodeInApp, - dynamicLinkDomain: actionCodeSettings.dynamicLinkDomain, + url: actionCodeSettings.url.toJS, + handleCodeInApp: actionCodeSettings.handleCodeInApp.toJS, + dynamicLinkDomain: actionCodeSettings.dynamicLinkDomain?.toJS, ); } else { webActionCodeSettings = auth_interop.ActionCodeSettings( - url: actionCodeSettings.url, - handleCodeInApp: actionCodeSettings.handleCodeInApp, + url: actionCodeSettings.url.toJS, + handleCodeInApp: actionCodeSettings.handleCodeInApp.toJS, ); } @@ -322,8 +308,8 @@ AuthCredential? convertWebAuthCredential( } return AuthCredential( - providerId: authCredential.providerId, - signInMethod: authCredential.signInMethod, + providerId: authCredential.providerId.toDart, + signInMethod: authCredential.signInMethod.toDart, ); } @@ -343,11 +329,11 @@ AuthCredential? convertWebOAuthCredential( return null; } - return OAuthProvider(authCredential.providerId).credential( - signInMethod: authCredential.signInMethod, - accessToken: authCredential.accessToken, - secret: authCredential.secret, - idToken: authCredential.idToken, + return OAuthProvider(authCredential.providerId.toDart).credential( + signInMethod: authCredential.signInMethod.toDart, + accessToken: authCredential.accessToken.toDart, + secret: authCredential.secret.toDart, + idToken: authCredential.idToken.toDart, ); } @@ -401,9 +387,9 @@ auth_interop.OAuthCredential? convertPlatformCredential( if (credential is OAuthCredential) { auth_interop.OAuthCredentialOptions credentialOptions = auth_interop.OAuthCredentialOptions( - accessToken: credential.accessToken, - rawNonce: credential.rawNonce, - idToken: credential.idToken, + accessToken: credential.accessToken?.toJS, + rawNonce: credential.rawNonce?.toJS, + idToken: credential.idToken?.toJS, ); return auth_interop.OAuthProvider(credential.providerId) .credential(credentialOptions); diff --git a/packages/firebase_auth/firebase_auth_web/pubspec.yaml b/packages/firebase_auth/firebase_auth_web/pubspec.yaml index cd01b6c493ab..142429e0f619 100644 --- a/packages/firebase_auth/firebase_auth_web/pubspec.yaml +++ b/packages/firebase_auth/firebase_auth_web/pubspec.yaml @@ -5,7 +5,7 @@ repository: https://github.com/firebase/flutterfire/tree/master/packages/firebas version: 5.8.13 environment: - sdk: '>=2.18.0 <4.0.0' + sdk: '>=3.2.0 <4.0.0' flutter: '>=3.3.0' dependencies: @@ -19,6 +19,7 @@ dependencies: http_parser: ^4.0.0 js: ^0.6.3 meta: ^1.8.0 + web: '>=0.3.0 <0.5.0' dev_dependencies: flutter_test: diff --git a/packages/firebase_core/firebase_core_web/lib/src/interop/utils/es6_interop.dart b/packages/firebase_core/firebase_core_web/lib/src/interop/utils/es6_interop.dart index 38c582de1e74..fea755d37bae 100644 --- a/packages/firebase_core/firebase_core_web/lib/src/interop/utils/es6_interop.dart +++ b/packages/firebase_core/firebase_core_web/lib/src/interop/utils/es6_interop.dart @@ -26,4 +26,7 @@ extension JSErrorExtension on JSError { external String? get name; external String? get message; external String? get code; + + // "customData" - see Firebase AuthError docs: https://firebase.google.com/docs/reference/js/auth.autherror + external dynamic get customData; }