diff --git a/packages/auth/android/src/main/java/io/invertase/firebase/auth/ReactNativeFirebaseAuthModule.java b/packages/auth/android/src/main/java/io/invertase/firebase/auth/ReactNativeFirebaseAuthModule.java index ad1244d04e..9db4f9b441 100644 --- a/packages/auth/android/src/main/java/io/invertase/firebase/auth/ReactNativeFirebaseAuthModule.java +++ b/packages/auth/android/src/main/java/io/invertase/firebase/auth/ReactNativeFirebaseAuthModule.java @@ -1188,7 +1188,7 @@ public void verifyPhoneNumberForMultiFactor( final Promise promise) { final MultiFactorSession multiFactorSession = mMultiFactorSessions.get(sessionKey); if (multiFactorSession == null) { - rejectPromiseWithCodeAndMessage(promise, "unknown", "can't find session for provided key"); + rejectPromiseWithCodeAndMessage(promise, "invalid-multi-factor-session", "can't find session for provided key"); return; } FirebaseApp firebaseApp = FirebaseApp.getInstance(appName); @@ -2553,6 +2553,10 @@ private WritableMap multiFactorInfoToMap(MultiFactorInfo hint) { hintMap.putString("factorId", hint.getFactorId()); hintMap.putString("uid", hint.getUid()); + if (hint.getFactorId().equals(PhoneMultiFactorGenerator.FACTOR_ID)) { + hintMap.putString("phoneNumber", ((PhoneMultiFactorInfo) hint).getPhoneNumber()); + } + return hintMap; } diff --git a/packages/auth/e2e/multiFactor.e2e.js b/packages/auth/e2e/multiFactor.e2e.js index 77aebf1387..d9201e4170 100644 --- a/packages/auth/e2e/multiFactor.e2e.js +++ b/packages/auth/e2e/multiFactor.e2e.js @@ -547,6 +547,7 @@ describe('multi-factor modular', function () { this.skip(); } const { phoneNumber, email, password } = await createUserWithMultiFactor(); + const maskedNumber = '+********' + phoneNumber.substring(phoneNumber.length - 4); const { signInWithEmailAndPassword, getAuth, getMultiFactorResolver } = authModular; @@ -562,6 +563,9 @@ describe('multi-factor modular', function () { multiFactorResolver.should.be.an.Object(); multiFactorResolver.hints.should.be.an.Array(); multiFactorResolver.hints.length.should.equal(1); + multiFactorResolver.hints[0].factorId.should.equal('phone'); + multiFactorResolver.hints[0].phoneNumber.should.equal(maskedNumber); + multiFactorResolver.session.should.be.a.String(); const verificationId = await new firebase.auth.PhoneAuthProvider( @@ -575,7 +579,6 @@ describe('multi-factor modular', function () { let verificationCode = await getLastSmsCode(phoneNumber); if (verificationCode == null) { // iOS simulator uses a masked phone number - const maskedNumber = '+********' + phoneNumber.substring(phoneNumber.length - 4); verificationCode = await getLastSmsCode(maskedNumber); } const phoneAuthCredential = new firebase.auth.PhoneAuthProvider.credential( @@ -591,6 +594,8 @@ describe('multi-factor modular', function () { user.email.should.equal('verified@example.com'); user.multiFactor.should.be.an.Object(); user.multiFactor.enrolledFactors.length.should.equal(1); + user.multiFactor.enrolledFactors[0].factorId.should.equal('phone'); + user.multiFactor.enrolledFactors[0].phoneNumber.should.equal(phoneNumber); return Promise.resolve(); }) .catch(e => { diff --git a/packages/auth/ios/RNFBAuth/RNFBAuthModule.m b/packages/auth/ios/RNFBAuth/RNFBAuthModule.m index 30290ace30..7425a1c021 100644 --- a/packages/auth/ios/RNFBAuth/RNFBAuthModule.m +++ b/packages/auth/ios/RNFBAuth/RNFBAuthModule.m @@ -578,7 +578,9 @@ - (void)invalidate { @"has expired or is not currently supported.", }]; } - DLog(@"using app SignInWithCredential: %@", firebaseApp.name)[[FIRAuth authWithApp:firebaseApp] + DLog(@"using app SignInWithCredential: %@", firebaseApp.name); + + [[FIRAuth authWithApp:firebaseApp] signInWithCredential:credential completion:^(FIRAuthDataResult *authResult, NSError *error) { if (error) { @@ -820,8 +822,9 @@ - (void)invalidate { : (NSString *)phoneNumber : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) { - DLog(@"SignInWthPhoneNumber instance: %@", - firebaseApp.name)[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]] + DLog(@"SignInWthPhoneNumber instance: %@", firebaseApp.name); + + [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]] verifyPhoneNumber:phoneNumber UIDelegate:nil completion:^(NSString *_Nullable verificationID, NSError *_Nullable error) { @@ -862,8 +865,9 @@ - (void)invalidate { }]; return; } - DLog(@"using instance verifyPhoneNumberWithMultiFactorInfo: %@", - firebaseApp.name)[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]] + DLog(@"using instance verifyPhoneNumberWithMultiFactorInfo: %@", firebaseApp.name); + + [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]] verifyPhoneNumberWithMultiFactorInfo:hint UIDelegate:nil multiFactorSession:session @@ -884,9 +888,19 @@ - (void)invalidate { : (NSString *)sessionId : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) { + DLog(@"verifyPhoneNumberForMultifactor using app: %@", firebaseApp.name); + DLog(@"verifyPhoneNumberForMultifactor phoneNumber: %@", phoneNumber); + DLog(@"verifyPhoneNumberForMultifactor sessionId: %@", sessionId); FIRMultiFactorSession *session = cachedSessions[sessionId]; - DLog(@"using instance VerifyPhoneNumberForMultifactor: %@", - firebaseApp.name)[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]] + if (session == nil) { + [RNFBSharedUtils rejectPromiseWithUserInfo:reject + userInfo:(NSMutableDictionary *)@{ + @"code" : @"invalid-multi-factor-session", + @"message" : @"can't find session for provided key" + }]; + return; + } + [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]] verifyPhoneNumber:phoneNumber UIDelegate:nil multiFactorSession:session @@ -907,12 +921,15 @@ - (void)invalidate { : (NSString *)verificationCode : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) { - DLog(@"using instance resolve MultiFactorSignIn: %@", firebaseApp.name) - FIRPhoneAuthCredential *credential = - [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]] - credentialWithVerificationID:verificationId - verificationCode:verificationCode]; - DLog(@"credential: %@", credential) FIRMultiFactorAssertion *assertion = + DLog(@"using instance resolve MultiFactorSignIn: %@", firebaseApp.name); + + FIRPhoneAuthCredential *credential = + [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]] + credentialWithVerificationID:verificationId + verificationCode:verificationCode]; + DLog(@"credential: %@", credential); + + FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential]; [cachedResolver[sessionKey] resolveSignInWithAssertion:assertion @@ -955,11 +972,12 @@ - (void)invalidate { : (NSString *_Nullable)displayName : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) { - DLog(@"using instance finalizeMultifactorEnrollment: %@", firebaseApp.name) - FIRPhoneAuthCredential *credential = - [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]] - credentialWithVerificationID:verificationId - verificationCode:verificationCode]; + DLog(@"using instance finalizeMultifactorEnrollment: %@", firebaseApp.name); + + FIRPhoneAuthCredential *credential = + [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]] + credentialWithVerificationID:verificationId + verificationCode:verificationCode]; FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential]; FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser; @@ -980,8 +998,9 @@ - (void)invalidate { : (FIRApp *)firebaseApp : (NSString *)phoneNumber : (NSString *)requestKey) { - DLog(@"using instance verifyPhoneNumber: %@", - firebaseApp.name)[[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]] + DLog(@"using instance verifyPhoneNumber: %@", firebaseApp.name); + + [[FIRPhoneAuthProvider providerWithAuth:[FIRAuth authWithApp:firebaseApp]] verifyPhoneNumber:phoneNumber UIDelegate:nil completion:^(NSString *_Nullable verificationID, NSError *_Nullable error) { @@ -1695,6 +1714,8 @@ - (NSDictionary *)firebaseUserToDict:(FIRUser *)user { @"enrollmentTime" : enrollmentTime, // @deprecated enrollmentDate kept for backwards compatibility, please use enrollmentTime @"enrollmentDate" : enrollmentTime, + // phoneNumber only present on FIRPhoneMultiFactorInfo + @"phoneNumber" : hint.phoneNumber == nil ? [NSNull null] : hint.phoneNumber, }]; } return enrolledFactors; diff --git a/packages/auth/lib/index.d.ts b/packages/auth/lib/index.d.ts index 90650342bf..1f1bf07119 100644 --- a/packages/auth/lib/index.d.ts +++ b/packages/auth/lib/index.d.ts @@ -472,7 +472,21 @@ export namespace FirebaseAuthTypes { /** * Contains information about a second factor. */ - export interface MultiFactorInfo { + export type MultiFactorInfo = PhoneMultiFactorInfo | TotpMultiFactorInfo; + + export interface PhoneMultiFactorInfo extends MultiFactorInfoCommon { + factorId: 'phone'; + /** + * The phone number used for this factor. + */ + phoneNumber: string; + } + + export interface TotpMultiFactorInfo extends MultiFactorInfoCommon { + factorId: 'totp'; + } + + export interface MultiFactorInfoCommon { /** * User friendly name for this factor. */ @@ -481,10 +495,6 @@ export namespace FirebaseAuthTypes { * Time the second factor was enrolled, in UTC. */ enrollmentTime: string; - /** - * Type of factor. - */ - factorId: FactorId; /** * Unique id for this factor. */