Skip to content
67 changes: 37 additions & 30 deletions FirebaseAuth/Sources/Swift/Auth/Auth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,12 @@ extension Auth: AuthInterop {
return
}
// Call back with current user token.
currentUser.internalGetToken(forceRefresh: forceRefresh) { token, error in
DispatchQueue.main.async {
callback(token, error)
currentUser
.internalGetToken(forceRefresh: forceRefresh, backend: strongSelf.backend) { token, error in
DispatchQueue.main.async {
callback(token, error)
}
}
}
}
}

Expand Down Expand Up @@ -294,7 +295,7 @@ extension Auth: AuthInterop {
requestConfiguration: self.requestConfiguration)
Task {
do {
let response = try await AuthBackend.call(with: request)
let response = try await self.backend.call(with: request)
Auth.wrapMainAsync(callback: completion, withParam: response.signinMethods, error: nil)
} catch {
Auth.wrapMainAsync(callback: completion, withParam: nil, error: error)
Expand Down Expand Up @@ -397,7 +398,7 @@ extension Auth: AuthInterop {
let response = try await injectRecaptcha(request: request,
action: AuthRecaptchaAction.signInWithPassword)
#else
let response = try await AuthBackend.call(with: request)
let response = try await backend.call(with: request)
#endif
return try await completeSignIn(
withAccessToken: response.idToken,
Expand Down Expand Up @@ -711,7 +712,7 @@ extension Auth: AuthInterop {
let request = SignUpNewUserRequest(requestConfiguration: self.requestConfiguration)
Task {
do {
let response = try await AuthBackend.call(with: request)
let response = try await self.backend.call(with: request)
let user = try await self.completeSignIn(
withAccessToken: response.idToken,
accessTokenExpirationDate: response.approximateExpirationDate,
Expand Down Expand Up @@ -773,7 +774,7 @@ extension Auth: AuthInterop {
requestConfiguration: self.requestConfiguration)
Task {
do {
let response = try await AuthBackend.call(with: request)
let response = try await self.backend.call(with: request)
let user = try await self.completeSignIn(
withAccessToken: response.idToken,
accessTokenExpirationDate: response.approximateExpirationDate,
Expand Down Expand Up @@ -883,7 +884,7 @@ extension Auth: AuthInterop {
if let inResponse {
response = inResponse
} else {
response = try await AuthBackend.call(with: request)
response = try await self.backend.call(with: request)
}
let user = try await self.completeSignIn(
withAccessToken: response.idToken,
Expand Down Expand Up @@ -995,7 +996,7 @@ extension Auth: AuthInterop {
requestConfiguration: self.requestConfiguration)
Task {
do {
let response = try await AuthBackend.call(with: request)
let response = try await self.backend.call(with: request)

let operation = ActionCodeInfo.actionCodeOperation(forRequestType: response.requestType)
guard let email = response.email else {
Expand Down Expand Up @@ -1434,7 +1435,7 @@ extension Auth: AuthInterop {
/// complete, or fails. Invoked asynchronously on the main thread in the future.
@objc open func revokeToken(withAuthorizationCode authorizationCode: String,
completion: ((Error?) -> Void)? = nil) {
currentUser?.internalGetToken { idToken, error in
currentUser?.internalGetToken(backend: backend) { idToken, error in
if let error {
Auth.wrapMainAsync(completion, error)
return
Expand Down Expand Up @@ -1615,7 +1616,9 @@ extension Auth: AuthInterop {

// MARK: Internal methods

init(app: FirebaseApp, keychainStorageProvider: AuthKeychainStorage = AuthKeychainStorageReal()) {
init(app: FirebaseApp,
keychainStorageProvider: AuthKeychainStorage = AuthKeychainStorageReal(),
backend: AuthBackend = AuthBackend(rpcIssuer: AuthBackendRPCIssuer())) {
Auth.setKeychainServiceNameForApp(app)
self.app = app
mainBundleUrlTypes = Bundle.main
Expand All @@ -1640,6 +1643,7 @@ extension Auth: AuthInterop {
auth: nil,
heartbeatLogger: app.heartbeatLogger,
appCheck: appCheck)
self.backend = backend
super.init()
requestConfiguration.auth = self

Expand Down Expand Up @@ -1913,17 +1917,18 @@ extension Auth: AuthInterop {
return
}
let uid = strongSelf.currentUser?.uid
strongSelf.currentUser?.internalGetToken(forceRefresh: true) { token, error in
if strongSelf.currentUser?.uid != uid {
return
}
if error != nil {
// Kicks off exponential back off logic to retry failed attempt. Starts with one minute
// delay (60 seconds) if this is the first failed attempt.
let rescheduleDelay = retry ? min(delay * 2, 16 * 60) : 60
strongSelf.scheduleAutoTokenRefresh(withDelay: rescheduleDelay, retry: true)
strongSelf.currentUser?
.internalGetToken(forceRefresh: true, backend: strongSelf.backend) { token, error in
if strongSelf.currentUser?.uid != uid {
return
}
if error != nil {
// Kicks off exponential back off logic to retry failed attempt. Starts with one minute
// delay (60 seconds) if this is the first failed attempt.
let rescheduleDelay = retry ? min(delay * 2, 16 * 60) : 60
strongSelf.scheduleAutoTokenRefresh(withDelay: rescheduleDelay, retry: true)
}
}
}
}
}

Expand Down Expand Up @@ -2077,7 +2082,7 @@ extension Auth: AuthInterop {
requestConfiguration: requestConfiguration)
request.autoCreate = !isReauthentication
credential.prepare(request)
let response = try await AuthBackend.call(with: request)
let response = try await backend.call(with: request)
if response.needConfirmation {
let email = response.email
let credential = OAuthCredential(withVerifyAssertionResponse: response)
Expand Down Expand Up @@ -2116,7 +2121,7 @@ extension Auth: AuthInterop {
phoneNumber: phoneNumber,
operation: operation,
requestConfiguration: requestConfiguration)
return try await AuthBackend.call(with: request)
return try await backend.call(with: request)
case let .verification(verificationID, code):
guard verificationID.count > 0 else {
throw AuthErrorUtils.missingVerificationIDError(message: nil)
Expand All @@ -2128,7 +2133,7 @@ extension Auth: AuthInterop {
verificationCode: code,
operation: operation,
requestConfiguration: requestConfiguration)
return try await AuthBackend.call(with: request)
return try await backend.call(with: request)
}
}
#endif
Expand All @@ -2154,7 +2159,7 @@ extension Auth: AuthInterop {
timestamp: credential.timestamp,
displayName: credential.displayName,
requestConfiguration: requestConfiguration)
let response = try await AuthBackend.call(with: request)
let response = try await backend.call(with: request)
let user = try await completeSignIn(withAccessToken: response.idToken,
accessTokenExpirationDate: response
.approximateExpirationDate,
Expand Down Expand Up @@ -2186,7 +2191,7 @@ extension Auth: AuthInterop {
let request = EmailLinkSignInRequest(email: email,
oobCode: actionCode,
requestConfiguration: requestConfiguration)
let response = try await AuthBackend.call(with: request)
let response = try await backend.call(with: request)
let user = try await completeSignIn(withAccessToken: response.idToken,
accessTokenExpirationDate: response
.approximateExpirationDate,
Expand Down Expand Up @@ -2244,7 +2249,7 @@ extension Auth: AuthInterop {
private func wrapAsyncRPCTask(_ request: any AuthRPCRequest, _ callback: ((Error?) -> Void)?) {
Task {
do {
let _ = try await AuthBackend.call(with: request)
let _ = try await self.backend.call(with: request)
Auth.wrapMainAsync(callback, nil)
} catch {
Auth.wrapMainAsync(callback, error)
Expand Down Expand Up @@ -2296,7 +2301,7 @@ extension Auth: AuthInterop {
action: action)
} else {
do {
return try await AuthBackend.call(with: request)
return try await backend.call(with: request)
} catch {
let nsError = error as NSError
if let underlyingError = nsError.userInfo[NSUnderlyingErrorKey] as? NSError,
Expand All @@ -2315,7 +2320,7 @@ extension Auth: AuthInterop {
}
}
}
return try await AuthBackend.call(with: request)
return try await backend.call(with: request)
}
#endif

Expand All @@ -2332,6 +2337,8 @@ extension Auth: AuthInterop {
/// Auth's backend.
var requestConfiguration: AuthRequestConfiguration

let backend: AuthBackend

#if os(iOS)

/// The manager for APNs tokens used by phone number auth.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ import Foundation
private func getHeadfulLiteUrl(eventID: String,
sessionID: String) async throws -> URL? {
let authDomain = try await AuthWebUtils
.fetchAuthDomain(withRequestConfiguration: auth.requestConfiguration)
.fetchAuthDomain(withRequestConfiguration: auth.requestConfiguration, backend: auth.backend)
let bundleID = Bundle.main.bundleIdentifier
let clientID = auth.app?.options.clientID
let appID = auth.app?.options.googleAppID
Expand Down
12 changes: 6 additions & 6 deletions FirebaseAuth/Sources/Swift/AuthProvider/PhoneAuthProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ import Foundation
.requestConfiguration)

do {
let response = try await AuthBackend.call(with: request)
let response = try await auth.backend.call(with: request)
return response.verificationID
} catch {
return try await handleVerifyErrorWithRetry(error: error,
Expand Down Expand Up @@ -245,7 +245,7 @@ import Foundation
requestConfiguration: auth.requestConfiguration
)

let response = try await AuthBackend.call(with: request)
let response = try await auth.backend.call(with: request)
return response.verificationID
}
guard let session else {
Expand All @@ -263,15 +263,15 @@ import Foundation
let request = StartMFAEnrollmentRequest(idToken: idToken,
enrollmentInfo: startMFARequestInfo,
requestConfiguration: auth.requestConfiguration)
let response = try await AuthBackend.call(with: request)
let response = try await auth.backend.call(with: request)
return response.phoneSessionInfo?.sessionInfo
} else {
let request = StartMFASignInRequest(MFAPendingCredential: session.mfaPendingCredential,
MFAEnrollmentID: session.multiFactorInfo?.uid,
signInInfo: startMFARequestInfo,
requestConfiguration: auth.requestConfiguration)

let response = try await AuthBackend.call(with: request)
let response = try await auth.backend.call(with: request)
return response.responseInfo?.sessionInfo
}
} catch {
Expand Down Expand Up @@ -328,7 +328,7 @@ import Foundation
isSandbox: token.type == AuthAPNSTokenType.sandbox,
requestConfiguration: auth.requestConfiguration)
do {
let verifyResponse = try await AuthBackend.call(with: request)
let verifyResponse = try await auth.backend.call(with: request)
guard let receipt = verifyResponse.receipt,
let timeout = verifyResponse.suggestedTimeOutDate?.timeIntervalSinceNow else {
fatalError("Internal Auth Error: invalid VerifyClientResponse")
Expand Down Expand Up @@ -436,7 +436,7 @@ import Foundation
/// - Parameter eventID: The event ID used for this purpose.
private func reCAPTCHAURL(withEventID eventID: String) async throws -> URL? {
let authDomain = try await AuthWebUtils
.fetchAuthDomain(withRequestConfiguration: auth.requestConfiguration)
.fetchAuthDomain(withRequestConfiguration: auth.requestConfiguration, backend: auth.backend)
let bundleID = Bundle.main.bundleIdentifier
let clientID = auth.app?.options.clientID
let appID = auth.app?.options.googleAppID
Expand Down
Loading
Loading