diff --git a/packages/auth/ios/RNFBAuth/RNFBAuthModule.m b/packages/auth/ios/RNFBAuth/RNFBAuthModule.m index 75fee58b71..372bc78be0 100644 --- a/packages/auth/ios/RNFBAuth/RNFBAuthModule.m +++ b/packages/auth/ios/RNFBAuth/RNFBAuthModule.m @@ -54,6 +54,7 @@ // Used for caching credentials between method calls. static __strong NSMutableDictionary *credentials; static __strong NSMutableDictionary *cachedResolver; +static __strong NSMutableDictionary *cachedSessions; @implementation RNFBAuthModule #pragma mark - @@ -73,6 +74,7 @@ - (id)init { idTokenHandlers = [[NSMutableDictionary alloc] init]; credentials = [[NSMutableDictionary alloc] init]; cachedResolver = [[NSMutableDictionary alloc] init]; + cachedSessions = [[NSMutableDictionary alloc] init]; }); return self; } @@ -99,6 +101,7 @@ - (void)invalidate { [credentials removeAllObjects]; [cachedResolver removeAllObjects]; + [cachedSessions removeAllObjects]; } #pragma mark - @@ -769,6 +772,26 @@ - (void)invalidate { } }]; } +RCT_EXPORT_METHOD(verifyPhoneNumberForMultiFactor + : (FIRApp *)firebaseApp + : (NSString *)phoneNumber + : (NSString *)sessionId + : (RCTPromiseResolveBlock)resolve + : (RCTPromiseRejectBlock)reject) { + FIRMultiFactorSession *session = cachedSessions[sessionId]; + [FIRPhoneAuthProvider.provider + verifyPhoneNumber:phoneNumber + UIDelegate:nil + multiFactorSession:session + completion:^(NSString *_Nullable verificationID, NSError *_Nullable error) { + if (error != nil) { + [self promiseRejectAuthException:reject error:error]; + return; + } + + resolve(verificationID); + }]; +} RCT_EXPORT_METHOD(resolveMultiFactorSignIn : (FIRApp *)firebaseApp @@ -797,6 +820,50 @@ - (void)invalidate { }]; } +RCT_EXPORT_METHOD(getSession + : (FIRApp *)firebaseApp + : (RCTPromiseResolveBlock)resolve + : (RCTPromiseRejectBlock)reject) { + FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser; + [[user multiFactor] getSessionWithCompletion:^(FIRMultiFactorSession *_Nullable session, + NSError *_Nullable error) { + if (error != nil) { + [self promiseRejectAuthException:reject error:error]; + return; + } + + NSString *sessionId = [NSString stringWithFormat:@"%@", @([session hash])]; + cachedSessions[sessionId] = session; + resolve(sessionId); + }]; +} + +RCT_EXPORT_METHOD(finalizeMultiFactorEnrollment + : (FIRApp *)firebaseApp + : (NSString *)verificationId + : (NSString *)verificationCode + : (NSString *_Nullable)displayName + : (RCTPromiseResolveBlock)resolve + : (RCTPromiseRejectBlock)reject) { + FIRPhoneAuthCredential *credential = + [FIRPhoneAuthProvider.provider credentialWithVerificationID:verificationId + verificationCode:verificationCode]; + FIRMultiFactorAssertion *assertion = + [FIRPhoneMultiFactorGenerator assertionWithCredential:credential]; + FIRUser *user = [FIRAuth authWithApp:firebaseApp].currentUser; + [user.multiFactor enrollWithAssertion:assertion + displayName:displayName + completion:^(NSError *_Nullable error) { + if (error != nil) { + [self promiseRejectAuthException:reject error:error]; + return; + } + + resolve(nil); + return; + }]; +} + RCT_EXPORT_METHOD(verifyPhoneNumber : (FIRApp *)firebaseApp : (NSString *)phoneNumber @@ -1080,25 +1147,11 @@ - (void)promiseNoUser:(RCTPromiseResolveBlock)resolve } - (NSDictionary *)multiFactorResolverToDict:(FIRMultiFactorResolver *)resolver { - NSMutableArray *hintsOutput = [NSMutableArray array]; - for (FIRPhoneMultiFactorInfo *hint in resolver.hints) { - NSString *enrollmentDate = - [[[NSISO8601DateFormatter alloc] init] stringFromDate:hint.enrollmentDate]; - - [hintsOutput addObject:@{ - @"uid" : hint.UID, - @"factorId" : [self getJSFactorId:(hint.factorID)], - @"displayName" : hint.displayName, - @"enrollmentDate" : enrollmentDate, - @"phoneNumber" : hint.phoneNumber - }]; - } - // Temporarily store the non-serializable session for later NSString *sessionHash = [NSString stringWithFormat:@"%@", @([resolver.session hash])]; return @{ - @"hints" : hintsOutput, + @"hints" : [self convertMultiFactorData:resolver.hints], @"session" : sessionHash, }; } @@ -1360,10 +1413,27 @@ - (NSDictionary *)firebaseUserToDict:(FIRUser *)user { @"refreshToken" : user.refreshToken, @"tenantId" : user.tenantID ? (id)user.tenantID : [NSNull null], keyUid : user.uid, - @"multiFactor" : user.multiFactor.enrolledFactors + @"multiFactor" : + @{@"enrolledFactors" : [self convertMultiFactorData:user.multiFactor.enrolledFactors]} }; } +- (NSArray *)convertMultiFactorData:(NSArray *)hints { + NSMutableArray *enrolledFactors = [NSMutableArray array]; + + for (FIRPhoneMultiFactorInfo *hint in hints) { + NSString *enrollmentDate = + [[[NSISO8601DateFormatter alloc] init] stringFromDate:hint.enrollmentDate]; + [enrolledFactors addObject:@{ + @"uid" : hint.UID, + @"factorId" : [self getJSFactorId:(hint.factorID)], + @"displayName" : hint.displayName == nil ? [NSNull null] : hint.displayName, + @"enrollmentDate" : enrollmentDate, + }]; + } + return enrolledFactors; +} + - (NSDictionary *)authCredentialToDict:(FIRAuthCredential *)authCredential { NSString *authCredentialHash = [NSString stringWithFormat:@"%@", @([authCredential hash])];