Skip to content

Commit

Permalink
feat(auth, web): finish phone web mfa
Browse files Browse the repository at this point in the history
  • Loading branch information
Lyokone committed Jul 11, 2022
1 parent 8278d3b commit c279c0f
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export 'package:firebase_auth_platform_interface/firebase_auth_platform_interfac
FirebaseAuthException,
FirebaseAuthMultiFactorException,
MultiFactorInfo,
PhoneMultiFactorGenerator,
PhoneMultiFactorInfo,
IdTokenResult,
UserMetadata,
Expand Down
11 changes: 11 additions & 0 deletions packages/firebase_auth/firebase_auth/lib/src/multi_factor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,14 @@ class MultiFactor {
return _delegate.getEnrolledFactors();
}
}

/// Provider for generating a PhoneMultiFactorAssertion.
class PhoneMultiFactorGenerator {
/// Transforms a PhoneAuthCredential into a [MultiFactorAssertion]
/// which can be used to confirm ownership of a phone second factor.
static MultiFactorAssertionPlatform getAssertion(
PhoneAuthCredential credential,
) {
return PhoneMultiFactorGeneratorPlatform.instance.getAssertion(credential);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,12 @@ class MultiFactorAssertion extends MultiFactorAssertionPlatform {
}

/// Helper class used to generate PhoneMultiFactorAssertions.
class MethodChannelPhoneMultiFactorGenerator extends PhoneMultiFactorGenerator {
class MethodChannelPhoneMultiFactorGenerator
extends PhoneMultiFactorGeneratorPlatform {
/// Transforms a PhoneAuthCredential into a [MultiFactorAssertion]
/// which can be used to confirm ownership of a phone second factor.
static MultiFactorAssertionPlatform getAssertion(
@override
MultiFactorAssertionPlatform getAssertion(
PhoneAuthCredential credential,
) {
return MultiFactorAssertion(credential);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:firebase_auth_platform_interface/firebase_auth_platform_interface.dart';
import 'package:firebase_auth_platform_interface/src/method_channel/method_channel_multi_factor.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';

/// {@template .platformInterfaceMultiFactor}
Expand Down Expand Up @@ -130,10 +131,31 @@ class PhoneMultiFactorInfo extends MultiFactorInfo {
}

/// Helper class used to generate PhoneMultiFactorAssertions.
class PhoneMultiFactorGenerator {
class PhoneMultiFactorGeneratorPlatform extends PlatformInterface {
static PhoneMultiFactorGeneratorPlatform? _instance;

static final Object _token = Object();

PhoneMultiFactorGeneratorPlatform() : super(token: _token);

/// The current default [PhoneMultiFactorGeneratorPlatform] instance.
///
/// It will always default to [MethodChannelPhoneMultiFactorGenerator]
/// if no other implementation was provided.
static PhoneMultiFactorGeneratorPlatform get instance {
_instance ??= MethodChannelPhoneMultiFactorGenerator();
return _instance!;
}

/// Sets the [PhoneMultiFactorGeneratorPlatform.instance]
static set instance(PhoneMultiFactorGeneratorPlatform instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}

/// Transforms a PhoneAuthCredential into a [MultiFactorAssertion]
/// which can be used to confirm ownership of a phone second factor.
static MultiFactorAssertionPlatform getAssertion(
MultiFactorAssertionPlatform getAssertion(
PhoneAuthCredential credential,
) {
throw UnimplementedError('getAssertion() is not implemented');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'dart:async';

import 'package:firebase_auth_platform_interface/firebase_auth_platform_interface.dart';
import 'package:firebase_auth_web/src/firebase_auth_web_multi_factor.dart';
import 'package:firebase_auth_web/src/interop/utils/utils.dart';
import 'package:firebase_auth_web/src/utils/web_utils.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_core_web/firebase_core_web.dart';
Expand Down Expand Up @@ -76,6 +77,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform {
static void registerWith(Registrar registrar) {
FirebaseCoreWeb.registerService('auth');
FirebaseAuthPlatform.instance = FirebaseAuthWeb.instance;
PhoneMultiFactorGeneratorPlatform.instance = PhoneMultiFactorGeneratorWeb();
RecaptchaVerifierFactoryPlatform.instance =
RecaptchaVerifierFactoryWeb.instance;
}
Expand Down Expand Up @@ -435,15 +437,16 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform {
}
}

print(data);
final phoneOptions = (data ?? phoneNumber)!;

final provider = auth_interop.PhoneAuthProvider(_webAuth);
final verifier = RecaptchaVerifierFactoryWeb(
auth: this,
).delegate;

final verificationId =
await provider.verifyPhoneNumber(data ?? phoneNumber, verifier);
/// We add the passthrough method for LegacyJsObject
final verificationId = await provider.verifyPhoneNumber(
jsify(phoneOptions, (object) => object), verifier);

codeSent(verificationId, null);
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:firebase_auth_platform_interface/firebase_auth_platform_interfac
import 'package:firebase_auth_web/firebase_auth_web.dart';
import 'package:firebase_auth_web/src/firebase_auth_web_user_credential.dart';

import 'interop/auth.dart' as auth;
import 'interop/multi_factor.dart' as multi_factor_interop;
import 'utils/web_utils.dart';

Expand All @@ -17,9 +18,6 @@ class MultiFactorWeb extends MultiFactorPlatform {

final multi_factor_interop.MultiFactorUser _webMultiFactorUser;

final mapAssertion =
<multi_factor_interop.MultiFactorAssertion, MultiFactorAssertionWeb>{};

@override
Future<MultiFactorSession> getSession() async {
try {
Expand All @@ -35,10 +33,9 @@ class MultiFactorWeb extends MultiFactorPlatform {
String? displayName,
}) async {
try {
final webAssertion = mapAssertion.keys
.firstWhere((element) => mapAssertion[element] == assertion);
final webAssertion = assertion as MultiFactorAssertionWeb;
return await _webMultiFactorUser.enroll(
webAssertion,
webAssertion.assertion,
displayName,
);
} catch (e) {
Expand Down Expand Up @@ -119,3 +116,29 @@ class MultiFactorSessionWeb extends MultiFactorSession {

final multi_factor_interop.MultiFactorSession webSession;
}

/// Helper class used to generate PhoneMultiFactorAssertions.
class PhoneMultiFactorGeneratorWeb extends PhoneMultiFactorGeneratorPlatform {
/// Transforms a PhoneAuthCredential into a [MultiFactorAssertion]
/// which can be used to confirm ownership of a phone second factor.
@override
MultiFactorAssertionPlatform getAssertion(
PhoneAuthCredential credential,
) {
final verificationId = credential.verificationId;
final verificationCode = credential.smsCode;

if (verificationCode == null) {
throw ArgumentError('verificationCode must not be null');
}
if (verificationId == null) {
throw ArgumentError('verificationId must not be null');
}

final cred =
auth.PhoneAuthProvider.credential(verificationId, verificationCode);

return MultiFactorAssertionWeb(
multi_factor_interop.PhoneMultiFactorGenerator.assertion(cred));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ class PhoneAuthProvider
/// Creates a new PhoneAuthProvider with the optional [Auth] instance
/// in which sign-ins should occur.
factory PhoneAuthProvider([Auth? auth]) =>
PhoneAuthProvider.fromJsObject((auth != null)
PhoneAuthProvider.fromJsObject(auth != null
? auth_interop.PhoneAuthProviderJsImpl(auth.jsObject)
: auth_interop.PhoneAuthProviderJsImpl());

Expand All @@ -931,10 +931,10 @@ class PhoneAuthProvider
/// Creates a phone auth credential given the verification ID
/// from [verifyPhoneNumber] and the [verificationCode] that was sent to the
/// user's mobile device.
static auth_interop.OAuthCredential credential(
static auth_interop.PhoneAuthCredentialJsImpl credential(
String verificationId, String verificationCode) =>
auth_interop.PhoneAuthProviderJsImpl.credential(
verificationId, verificationCode) as auth_interop.OAuthCredential;
verificationId, verificationCode);
}

/// A verifier for domain verification and abuse prevention.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ class PhoneAuthProviderJsImpl extends AuthProviderJsImpl {
dynamic /* PhoneInfoOptions | string */ phoneOptions,
ApplicationVerifierJsImpl applicationVerifier,
);
external static AuthCredential credential(
external static PhoneAuthCredentialJsImpl credential(
String verificationId,
String verificationCode,
);
Expand Down Expand Up @@ -731,8 +731,7 @@ class PhoneMultiFactorEnrollInfoOptionsJsImpl {
}

/// https://firebase.google.com/docs/reference/js/auth.phonemultifactorgenerator
@JS()
@anonymous
@JS('PhoneMultiFactorGenerator')
class PhoneMultiFactorGeneratorJsImpl {
external static String get FACTOR_ID;
external static PhoneMultiFactorAssertionJsImpl? assertion(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,17 @@ class MultiFactorResolver
.then(auth.UserCredential.fromJsObject);
}
}

/// https://firebase.google.com/docs/reference/js/auth.multifactorsession.md#multifactorsession_interface
class PhoneMultiFactorGenerator
extends JsObjectWrapper<auth_interop.PhoneMultiFactorGeneratorJsImpl> {
PhoneMultiFactorGenerator.fromJsObject(
auth.PhoneMultiFactorGeneratorJsImpl jsObject)
: super.fromJsObject(jsObject);

static PhoneMultiFactorAssertion assertion(
auth.PhoneAuthCredentialJsImpl credential) {
return PhoneMultiFactorAssertion.fromJsObject(
auth_interop.PhoneMultiFactorGeneratorJsImpl.assertion(credential)!);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ dynamic dartify(Object jsObject) {
}

/// Returns the JS implementation from Dart Object.
dynamic jsify(Object dartObject) {
return core_interop.jsify(dartObject);
dynamic jsify(
Object dartObject, [
Object? Function(Object? object)? customJsify,
]) {
return core_interop.jsify(dartObject, customJsify);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ 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:flutter/material.dart';

import '../interop/auth.dart' as auth_interop;
import '../interop/multi_factor.dart' as multi_factor_interop;
Expand Down Expand Up @@ -57,7 +56,6 @@ FirebaseAuthException getFirebaseAuthException(
tenantId: firebaseError.tenantId,
resolver: MultiFactorResolverWeb(
resolverWeb.hints.map((e) {
print(e);
if (e is multi_factor_interop.PhoneMultiFactorInfo) {
return PhoneMultiFactorInfo(
displayName: e.displayName,
Expand Down Expand Up @@ -307,7 +305,7 @@ auth_interop.OAuthCredential? convertPlatformCredential(
return auth_interop.PhoneAuthProvider.credential(
credential.verificationId!,
credential.smsCode!,
);
) as auth_interop.OAuthCredential;
}

if (credential is OAuthCredential) {
Expand Down

0 comments on commit c279c0f

Please sign in to comment.