From 70ec07f5f378f6eb5efb458c4413f44d6ca83421 Mon Sep 17 00:00:00 2001 From: Sebastian Villena <97059974+ruisebas@users.noreply.github.com> Date: Fri, 13 Dec 2024 15:23:59 -0500 Subject: [PATCH] fix: Avoid signing out users when the token refresh failed due to connectivity issues on startup --- .../Extensions/AuthError+Connectivity.swift | 26 +++++++++++++++++++ .../Models/AuthenticatorState.swift | 9 +++++-- .../States/AuthenticatorBaseState.swift | 16 +----------- 3 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 Sources/Authenticator/Extensions/AuthError+Connectivity.swift diff --git a/Sources/Authenticator/Extensions/AuthError+Connectivity.swift b/Sources/Authenticator/Extensions/AuthError+Connectivity.swift new file mode 100644 index 0000000..a025a3f --- /dev/null +++ b/Sources/Authenticator/Extensions/AuthError+Connectivity.swift @@ -0,0 +1,26 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import Amplify +import Foundation + +extension AuthError { + var isConnectivityError: Bool { + guard let error = underlyingError as? NSError else { + return false + } + + let networkErrorCodes = [ + NSURLErrorCannotFindHost, + NSURLErrorCannotConnectToHost, + NSURLErrorNetworkConnectionLost, + NSURLErrorDNSLookupFailed, + NSURLErrorNotConnectedToInternet + ] + return networkErrorCodes.contains(where: { $0 == error.code }) + } +} diff --git a/Sources/Authenticator/Models/AuthenticatorState.swift b/Sources/Authenticator/Models/AuthenticatorState.swift index c02a3b2..c5568f8 100644 --- a/Sources/Authenticator/Models/AuthenticatorState.swift +++ b/Sources/Authenticator/Models/AuthenticatorState.swift @@ -116,12 +116,17 @@ public class AuthenticatorState: ObservableObject, AuthenticatorStateProtocol { return session.isSignedIn } - if configuration.hasIdentityPool, case .failure(_) = cognitoSession.getIdentityId() { + // If the failures are caused due to connectivity errors, consider the session still valid + if configuration.hasIdentityPool, + case .failure(let authError) = cognitoSession.getIdentityId(), + !authError.isConnectivityError { log.verbose("Could not fetch Identity ID") return false } - if configuration.hasUserPool, case .failure(_) = cognitoSession.getCognitoTokens(){ + if configuration.hasUserPool, + case .failure(let authError) = cognitoSession.getCognitoTokens(), + !authError.isConnectivityError { log.verbose("Could not fetch Cognito Tokens") return false } diff --git a/Sources/Authenticator/States/AuthenticatorBaseState.swift b/Sources/Authenticator/States/AuthenticatorBaseState.swift index 127593f..91996fe 100644 --- a/Sources/Authenticator/States/AuthenticatorBaseState.swift +++ b/Sources/Authenticator/States/AuthenticatorBaseState.swift @@ -227,7 +227,7 @@ public class AuthenticatorBaseState: ObservableObject { } // First check if the underlying error is a connectivity one - if isConnectivityError(error.underlyingError) { + if error.isConnectivityError { log.verbose("The error is identified as a connectivity issue, displaying the corresponding localized string.") return "authenticator.cognitoError.network".localized() } @@ -248,20 +248,6 @@ public class AuthenticatorBaseState: ObservableObject { log.verbose("No localizable string was found for error of type '\(cognitoError)'") return nil } - - private func isConnectivityError(_ error: Error?) -> Bool { - guard let error = error as? NSError else { - return false - } - let networkErrorCodes = [ - NSURLErrorCannotFindHost, - NSURLErrorCannotConnectToHost, - NSURLErrorNetworkConnectionLost, - NSURLErrorDNSLookupFailed, - NSURLErrorNotConnectedToInternet - ] - return networkErrorCodes.contains(where: { $0 == error.code }) - } } extension AuthenticatorBaseState: Equatable {