4343#import " FirebaseAuth/Sources/Backend/RPC/FIRSetAccountInfoResponse.h"
4444#import " FirebaseAuth/Sources/Backend/RPC/FIRSignInWithGameCenterRequest.h"
4545#import " FirebaseAuth/Sources/Backend/RPC/FIRSignInWithGameCenterResponse.h"
46+ #import " FirebaseAuth/Sources/Backend/RPC/FIRSignUpNewUserRequest.h"
47+ #import " FirebaseAuth/Sources/Backend/RPC/FIRSignUpNewUserResponse.h"
4648#import " FirebaseAuth/Sources/Backend/RPC/FIRVerifyAssertionRequest.h"
4749#import " FirebaseAuth/Sources/Backend/RPC/FIRVerifyAssertionResponse.h"
4850#import " FirebaseAuth/Sources/Backend/RPC/FIRVerifyCustomTokenRequest.h"
6163#import " FirebaseAuth/Sources/Utilities/FIRAuthWebUtils.h"
6264
6365#if TARGET_OS_IOS
64- #import " FirebaseAuth/Sources/Public/FirebaseAuth/FIRPhoneAuthProvider.h"
65-
6666#import " FirebaseAuth/Sources/AuthProvider/Phone/FIRPhoneAuthCredential_Internal.h"
67+ #import " FirebaseAuth/Sources/Public/FirebaseAuth/FIRPhoneAuthProvider.h"
68+ #import " FirebaseAuth/Sources/Utilities/FIRAuthRecaptchaVerifier.h"
6769#endif
6870
6971NS_ASSUME_NONNULL_BEGIN
@@ -582,7 +584,6 @@ - (void)setTokenService:(FIRSecureTokenService *)tokenService
582584}
583585
584586#pragma mark -
585-
586587/* * @fn updateEmail:password:callback:
587588 @brief Updates email address and/or password for the current user.
588589 @remarks May fail if there is already an email/password-based account for the same email
@@ -1079,6 +1080,109 @@ - (void)internalVerifyBeforeUpdateEmailWithNewEmail:(NSString *)newEmail
10791080 });
10801081}
10811082
1083+ - (void )linkWithEmailPassword : (FIREmailPasswordAuthCredential *)credential
1084+ authResult : (FIRAuthDataResult *)authResult
1085+ completion : (nullable FIRAuthDataResultCallback)completion {
1086+ [self internalGetTokenWithCallback: ^(NSString *_Nullable accessToken, NSError *_Nullable error) {
1087+ FIRAuthRequestConfiguration *requestConfiguration = self.auth .requestConfiguration ;
1088+ FIRSignUpNewUserRequest *request =
1089+ [[FIRSignUpNewUserRequest alloc ] initWithEmail: credential.email
1090+ password: credential.password
1091+ displayName: nil
1092+ idToken: accessToken
1093+ requestConfiguration: requestConfiguration];
1094+ FIRSignupNewUserCallback signUpNewUserCallback = ^(FIRSignUpNewUserResponse *_Nullable response,
1095+ NSError *_Nullable error) {
1096+ if (error) {
1097+ [self signOutIfTokenIsInvalidWithError: error];
1098+ callInMainThreadWithAuthDataResultAndError (completion, nil , error);
1099+ } else {
1100+ // Update the new token and refresh user info again.
1101+ self->_tokenService = [[FIRSecureTokenService alloc ]
1102+ initWithRequestConfiguration: requestConfiguration
1103+ accessToken: response.IDToken
1104+ accessTokenExpirationDate: response.approximateExpirationDate
1105+ refreshToken: response.refreshToken];
1106+
1107+ [self internalGetTokenWithCallback: ^(NSString *_Nullable accessToken,
1108+ NSError *_Nullable error) {
1109+ if (error) {
1110+ callInMainThreadWithAuthDataResultAndError (completion, nil , error);
1111+ return ;
1112+ }
1113+ FIRGetAccountInfoRequest *getAccountInfoRequest =
1114+ [[FIRGetAccountInfoRequest alloc ] initWithAccessToken: accessToken
1115+ requestConfiguration: requestConfiguration];
1116+ [FIRAuthBackend
1117+ getAccountInfo: getAccountInfoRequest
1118+ callback: ^(FIRGetAccountInfoResponse *_Nullable response,
1119+ NSError *_Nullable error) {
1120+ if (error) {
1121+ [self signOutIfTokenIsInvalidWithError: error];
1122+ callInMainThreadWithAuthDataResultAndError (completion, nil , error);
1123+ return ;
1124+ }
1125+ self.anonymous = NO ;
1126+ [self updateWithGetAccountInfoResponse: response];
1127+ NSError *keychainError;
1128+ if (![self updateKeychain: &keychainError]) {
1129+ callInMainThreadWithAuthDataResultAndError (completion, nil , keychainError);
1130+ return ;
1131+ }
1132+ [self signOutIfTokenIsInvalidWithError: error];
1133+ callInMainThreadWithAuthDataResultAndError (completion, authResult, nil );
1134+ }];
1135+ }];
1136+ }
1137+ };
1138+
1139+ #if TARGET_OS_IOS && !TARGET_OS_MACCATALYST && (!defined(TARGET_OS_VISION) || !TARGET_OS_VISION)
1140+ if ([[FIRAuthRecaptchaVerifier sharedRecaptchaVerifier: self .auth]
1141+ enablementStatusForProvider: FIRAuthRecaptchaProviderPassword]) {
1142+ [[FIRAuthRecaptchaVerifier sharedRecaptchaVerifier: self .auth]
1143+ injectRecaptchaFields: request
1144+ provider: FIRAuthRecaptchaProviderPassword
1145+ action: FIRAuthRecaptchaActionSignUpPassword
1146+ completion: ^(
1147+ FIRIdentityToolkitRequest<FIRAuthRPCRequest> *requestWithRecaptchaToken) {
1148+ [FIRAuthBackend
1149+ signUpNewUser: (FIRSignUpNewUserRequest *)requestWithRecaptchaToken
1150+ callback: signUpNewUserCallback];
1151+ }];
1152+ } else {
1153+ [FIRAuthBackend
1154+ signUpNewUser: request
1155+ callback: ^(FIRSignUpNewUserResponse *_Nullable response, NSError *_Nullable error) {
1156+ if (!error) {
1157+ signUpNewUserCallback (response, nil );
1158+ return ;
1159+ }
1160+ NSError *underlyingError = [error.userInfo objectForKey: NSUnderlyingErrorKey ];
1161+ if (error.code == FIRAuthErrorCodeInternalError &&
1162+ [[underlyingError.userInfo
1163+ objectForKey: FIRAuthErrorUserInfoDeserializedResponseKey][@" message" ]
1164+ hasPrefix: kMissingRecaptchaTokenErrorPrefix ]) {
1165+ [[FIRAuthRecaptchaVerifier sharedRecaptchaVerifier: self .auth]
1166+ injectRecaptchaFields: request
1167+ provider: FIRAuthRecaptchaProviderPassword
1168+ action: FIRAuthRecaptchaActionSignUpPassword
1169+ completion: ^(FIRIdentityToolkitRequest<FIRAuthRPCRequest>
1170+ *requestWithRecaptchaToken) {
1171+ [FIRAuthBackend signUpNewUser: (FIRSignUpNewUserRequest *)
1172+ requestWithRecaptchaToken
1173+ callback: signUpNewUserCallback];
1174+ }];
1175+ } else {
1176+ signUpNewUserCallback (nil , error);
1177+ }
1178+ }];
1179+ }
1180+ #else
1181+ [FIRAuthBackend signUpNewUser: request callback: signUpNewUserCallback];
1182+ #endif
1183+ }];
1184+ }
1185+
10821186- (void )linkWithCredential : (FIRAuthCredential *)credential
10831187 completion : (nullable FIRAuthDataResultCallback)completion {
10841188 dispatch_async (FIRAuthGlobalWorkQueue (), ^{
@@ -1098,15 +1202,9 @@ - (void)linkWithCredential:(FIRAuthCredential *)credential
10981202 FIREmailPasswordAuthCredential *emailPasswordCredential =
10991203 (FIREmailPasswordAuthCredential *)credential;
11001204 if (emailPasswordCredential.password ) {
1101- [self updateEmail: emailPasswordCredential.email
1102- password: emailPasswordCredential.password
1103- callback: ^(NSError *error) {
1104- if (error) {
1105- callInMainThreadWithAuthDataResultAndError (completion, nil , error);
1106- } else {
1107- callInMainThreadWithAuthDataResultAndError (completion, result, nil );
1108- }
1109- }];
1205+ [self linkWithEmailPassword: emailPasswordCredential
1206+ authResult: result
1207+ completion: completion];
11101208 } else {
11111209 [self internalGetTokenWithCallback: ^(NSString *_Nullable accessToken,
11121210 NSError *_Nullable error) {
0 commit comments