From b38c6f6bb2c0494440bf0266d86ed499bca6d0d6 Mon Sep 17 00:00:00 2001 From: Liubin Jiang <56564857+Xiaoshouzi-gh@users.noreply.github.com> Date: Fri, 5 Apr 2024 11:10:56 -0700 Subject: [PATCH] fix the sign in with deleted passkey crash issue (#12710) --- FirebaseAuth/Sources/Auth/FIRAuth.m | 1 + FirebaseAuth/Sources/Backend/FIRAuthBackend.m | 13 +++++++++++-- .../Sources/Public/FirebaseAuth/FIRAuthErrors.h | 4 ++++ FirebaseAuth/Sources/User/FIRUser.m | 1 + FirebaseAuth/Sources/Utilities/FIRAuthErrorUtils.h | 6 ++++++ FirebaseAuth/Sources/Utilities/FIRAuthErrorUtils.m | 11 +++++++++++ .../Sources/Utilities/FIRAuthInternalErrors.h | 6 ++++++ 7 files changed, 40 insertions(+), 2 deletions(-) diff --git a/FirebaseAuth/Sources/Auth/FIRAuth.m b/FirebaseAuth/Sources/Auth/FIRAuth.m index f8d8259ff0b..bce46c7f275 100644 --- a/FirebaseAuth/Sources/Auth/FIRAuth.m +++ b/FirebaseAuth/Sources/Auth/FIRAuth.m @@ -1281,6 +1281,7 @@ - (void)finalizePasskeySignInWithPlatformCredential: NSError *_Nullable error) { if (error) { decoratedCallback(nil, error); + return; } [self completeSignInWithAccessToken:response.idToken accessTokenExpirationDate:nil diff --git a/FirebaseAuth/Sources/Backend/FIRAuthBackend.m b/FirebaseAuth/Sources/Backend/FIRAuthBackend.m index 37fc1899aca..ea1d2ab8112 100644 --- a/FirebaseAuth/Sources/Backend/FIRAuthBackend.m +++ b/FirebaseAuth/Sources/Backend/FIRAuthBackend.m @@ -561,10 +561,16 @@ /** @var kInvalidLoginCredentials @brief This is the error message the server will respond with if the login credentials is - invalid. in the request. + invalid in the request. */ static NSString *const kInvalidLoginCredentials = @"INVALID_LOGIN_CREDENTIALS"; +/** @var kPasskeyEnrollmentNotFound + @brief This is the error message the server will respond with if the passkey credentials is + invalid in the request. + */ +static NSString *const kPasskeyEnrollmentNotFound = @"PASSKEY_ENROLLMENT_NOT_FOUND"; + /** @var gBackendImplementation @brief The singleton FIRAuthBackendImplementation instance to use. */ @@ -1400,7 +1406,6 @@ - (void)callWithRequest:(id)request underlyingError:error]); return; } - // Finally, we try to populate the response object with the JSON // values. if (![response setWithDictionary:dictionary error:&error]) { @@ -1475,6 +1480,10 @@ + (nullable NSError *)clientErrorWithServerErrorMessage:(NSString *)serverErrorM return [FIRAuthErrorUtils userNotFoundErrorWithMessage:serverDetailErrorMessage]; } + if ([shortErrorMessage isEqualToString:kPasskeyEnrollmentNotFound]) { + return [FIRAuthErrorUtils passkeyEnrollmentNotFoundError]; + } + if ([shortErrorMessage isEqualToString:kUserDeletedErrorMessage]) { return [FIRAuthErrorUtils userNotFoundErrorWithMessage:serverDetailErrorMessage]; } diff --git a/FirebaseAuth/Sources/Public/FirebaseAuth/FIRAuthErrors.h b/FirebaseAuth/Sources/Public/FirebaseAuth/FIRAuthErrors.h index d6bfa44979f..59badcfac5b 100644 --- a/FirebaseAuth/Sources/Public/FirebaseAuth/FIRAuthErrors.h +++ b/FirebaseAuth/Sources/Public/FirebaseAuth/FIRAuthErrors.h @@ -458,6 +458,10 @@ typedef NS_ERROR_ENUM(FIRAuthErrorDomain, FIRAuthErrorCode){ */ FIRAuthErrorCodeRecaptchaSDKNotLinked = 17208, + /** Indicates the user account was not found. + */ + FIRAuthErrorCodePasskeyEnrollmentNotFound = 17209, + /** Indicates an error occurred while attempting to access the keychain. */ FIRAuthErrorCodeKeychainError = 17995, diff --git a/FirebaseAuth/Sources/User/FIRUser.m b/FirebaseAuth/Sources/User/FIRUser.m index 1d2e3e93987..f1ae5c706dc 100644 --- a/FirebaseAuth/Sources/User/FIRUser.m +++ b/FirebaseAuth/Sources/User/FIRUser.m @@ -673,6 +673,7 @@ - (void)finalizePasskeyEnrollmentWithPlatformCredential: NSError *_Nullable error) { if (error) { decoratedCallback(nil, error); + return; } else { [FIRAuth.auth completeSignInWithAccessToken:response.idToken diff --git a/FirebaseAuth/Sources/Utilities/FIRAuthErrorUtils.h b/FirebaseAuth/Sources/Utilities/FIRAuthErrorUtils.h index 0e5e4b4c072..c384f2781eb 100644 --- a/FirebaseAuth/Sources/Utilities/FIRAuthErrorUtils.h +++ b/FirebaseAuth/Sources/Utilities/FIRAuthErrorUtils.h @@ -489,6 +489,12 @@ static NSString *const kMissingRecaptchaTokenErrorPrefix = @"MISSING_RECAPTCHA_T */ + (NSError *)notificationNotForwardedError; +/** @fn passkeyEnrollmentNotFoundError + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeNotificationNotForwarded code. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)passkeyEnrollmentNotFoundError; + #if TARGET_OS_IOS /** @fn secondFactorRequiredError @brief Constructs an @c NSError with the @c FIRAuthErrorCodeSecondFactorRequired code. diff --git a/FirebaseAuth/Sources/Utilities/FIRAuthErrorUtils.m b/FirebaseAuth/Sources/Utilities/FIRAuthErrorUtils.m index 5eb531b749d..42b6cc4a9e3 100644 --- a/FirebaseAuth/Sources/Utilities/FIRAuthErrorUtils.m +++ b/FirebaseAuth/Sources/Utilities/FIRAuthErrorUtils.m @@ -630,6 +630,9 @@ @"Login credentials invalid. It is possible that the email/password combination does not " @"exist."; +static NSString *const kFIRAuthErrorMessageMissingPasskeyEnrollment = + @"Cannot find the passkey linked to the current account."; + /** @var FIRAuthErrorDescription @brief The error descrioption, based on the error code. @remarks No default case so that we get a compiler warning if a new value was added to the enum. @@ -814,6 +817,8 @@ return kFIRAuthErrorMessageInvalidReqType; case FIRAuthErrorCodeRecaptchaSDKNotLinked: return kFIRAuthErrorMessageRecaptchaSDKNotLinked; + case FIRAuthErrorCodePasskeyEnrollmentNotFound: + return kFIRAuthErrorMessageMissingPasskeyEnrollment; } } @@ -1001,6 +1006,8 @@ return @"ERROR_INVALID_REQ_TYPE"; case FIRAuthErrorCodeRecaptchaSDKNotLinked: return @"ERROR_RECAPTCHA_SDK_NOT_LINKED"; + case FIRAuthErrorCodePasskeyEnrollmentNotFound: + return @"ERROR_PASSKEY_ENROLLMENT_NOT_FOUND"; } } @@ -1239,6 +1246,10 @@ + (NSError *)userNotFoundErrorWithMessage:(nullable NSString *)message { return [self errorWithCode:FIRAuthInternalErrorCodeUserNotFound message:message]; } ++ (NSError *)passkeyEnrollmentNotFoundError { + return [self errorWithCode:FIRAuthInternalPasskeyEnrollmentNotFound]; +} + + (NSError *)invalidAPIKeyError { return [self errorWithCode:FIRAuthInternalErrorCodeInvalidAPIKey]; } diff --git a/FirebaseAuth/Sources/Utilities/FIRAuthInternalErrors.h b/FirebaseAuth/Sources/Utilities/FIRAuthInternalErrors.h index 82b99b6487d..218518f738e 100644 --- a/FirebaseAuth/Sources/Utilities/FIRAuthInternalErrors.h +++ b/FirebaseAuth/Sources/Utilities/FIRAuthInternalErrors.h @@ -175,6 +175,12 @@ typedef NS_ENUM(NSInteger, FIRAuthInternalErrorCode) { */ FIRAuthInternalErrorCodeUserNotFound = FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeUserNotFound, + /** @var FIRAuthInternalPasskeyEnrollmentNotFound + @brief Indicates the given credential ID doesn't exist for passkey withdrawal. + */ + FIRAuthInternalPasskeyEnrollmentNotFound = FIRAuthPublicErrorCodeFlag | + FIRAuthErrorCodePasskeyEnrollmentNotFound, + /** @var FIRAuthInternalErrorCodeInvalidAPIKey @brief Indicates an invalid API Key was supplied in the request. */