Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions FirebaseAuth/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Unreleased
- [fixed] Add a mechanism to prevent concurrent token refreshes. (#15474)
- [fixed] Fix handling of AppCheck placeholder tokens. (#15372)

# 12.2.0
- [added] Added TOTP support for macOS.
Expand Down
4 changes: 2 additions & 2 deletions FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,8 @@ import Foundation
let tokenResult = await appCheck.getToken(forcingRefresh: false)
if let error = tokenResult.error {
AuthLog.logWarning(code: "I-AUT000018",
message: "Error getting App Check token; using placeholder " +
"token instead. Error: \(error)")
message: "Error getting App Check token. Error: \(error)")
throw error
}
let appCheckTokenFragment = "fac=\(tokenResult.token)"
components?.fragment = appCheckTokenFragment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -627,8 +627,8 @@ import Foundation
let tokenResult = await appCheck.getToken(forcingRefresh: false)
if let error = tokenResult.error {
AuthLog.logWarning(code: "I-AUT000018",
message: "Error getting App Check token; using placeholder " +
"token instead. Error: \(error)")
message: "Error getting App Check token. Error: \(error)")
throw error
}
let appCheckTokenFragment = "fac=\(tokenResult.token)"
components?.fragment = appCheckTokenFragment
Expand Down
6 changes: 4 additions & 2 deletions FirebaseAuth/Tests/Unit/Fakes/FakeAppCheck.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import Foundation

class FakeAppCheck: NSObject, AppCheckInterop {
let fakeAppCheckToken = "fakeAppCheckToken"
var error: Error?

func getToken(forcingRefresh: Bool, completion: @escaping AppCheckTokenHandlerInterop) {
completion(FakeAppCheckResult(token: "fakeAppCheckToken"))
completion(FakeAppCheckResult(token: "fakeAppCheckToken", error: error))
}

func tokenDidChangeNotificationName() -> String {
Expand All @@ -40,7 +41,8 @@ class FakeAppCheckResult: NSObject, FIRAppCheckTokenResultInterop {
var token: String
var error: Error?

init(token: String) {
init(token: String, error: Error? = nil) {
self.token = token
self.error = error
}
}
32 changes: 32 additions & 0 deletions FirebaseAuth/Tests/Unit/OAuthProviderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,38 @@ import FirebaseCore
OAuthProviderTests.testAppCheck = false
}

func testGetCredentialWithUIDelegateWithAppCheckError() throws {
let expectation = self.expectation(description: "App Check error propagated")
let fakeAppCheck = FakeAppCheck()
let expectedError = NSError(domain: "appCheckError", code: -1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low

For improved maintainability and to avoid magic strings, consider defining "appCheckError" and -1 as private constants at the top of the OAuthProviderTests class. This would align with the existing practice for other test constants in this file.

fakeAppCheck.error = expectedError
initApp(#function, useAppID: true)
let auth = try XCTUnwrap(OAuthProviderTests.auth)
auth.requestConfiguration.appCheck = fakeAppCheck
let provider = OAuthProvider(providerID: kFakeProviderID, auth: auth)

let projectConfigExpectation = self.expectation(description: "projectConfiguration")
rpcIssuer.projectConfigRequester = { request in
projectConfigExpectation.fulfill()
do {
return try self.rpcIssuer.respond(withJSON: ["authorizedDomains": [
Self.kFakeAuthorizedWebDomain,
Self.kFakeAuthorizedDomain,
]])
} catch {
XCTFail("Failure sending response: \(error)")
return (nil, nil)
}
}

provider.getCredentialWith(nil) { credential, error in
XCTAssertNil(credential)
XCTAssertEqual(error as? NSError, expectedError)
expectation.fulfill()
}
waitForExpectations(timeout: 2.0)
}

/** @fn testOAuthCredentialCoding
@brief Tests successful archiving and unarchiving of @c GoogleAuthCredential.
*/
Expand Down
27 changes: 23 additions & 4 deletions FirebaseAuth/Tests/Unit/PhoneAuthProviderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -762,10 +762,12 @@
bothClientAndAppID: Bool = false,
reCAPTCHAfallback: Bool = false,
forwardingNotification: Bool = true,
presenterError: Error? = nil) async throws {
presenterError: Error? = nil,
fakeAppCheck: FakeAppCheck? = nil) async throws {
initApp(function, useClientID: useClientID, bothClientAndAppID: bothClientAndAppID,
testMode: testMode,
forwardingNotification: forwardingNotification)
forwardingNotification: forwardingNotification,
fakeAppCheck: fakeAppCheck)
let auth = try XCTUnwrap(PhoneAuthProviderTests.auth)
let provider = PhoneAuthProvider.provider(auth: auth)
var expectations: [XCTestExpectation] = []
Expand Down Expand Up @@ -807,7 +809,7 @@
presenterError: presenterError
)
}
if errorURLString == nil, presenterError == nil {
if errorURLString == nil, presenterError == nil, fakeAppCheck?.error == nil {
let requestExpectation = expectation(description: "verifyRequester")
expectations.append(requestExpectation)
rpcIssuer.verifyRequester = { request in
Expand Down Expand Up @@ -861,7 +863,8 @@
bothClientAndAppID: Bool = false,
testMode: Bool = false,
forwardingNotification: Bool = true,
fakeToken: Bool = false) {
fakeToken: Bool = false,
fakeAppCheck: FakeAppCheck? = nil) {
let options = FirebaseOptions(googleAppID: "0:0000000000000:ios:0000000000000000",
gcmSenderID: "00000000000000000-00000000000-000000000")
options.apiKey = PhoneAuthProviderTests.kFakeAPIKey
Expand All @@ -884,6 +887,9 @@
kAuthGlobalWorkQueue.sync {
// Wait for Auth protectedDataInitialization to finish.
PhoneAuthProviderTests.auth = auth
if let fakeAppCheck = fakeAppCheck {
auth.requestConfiguration.appCheck = fakeAppCheck
}
if testMode {
// Disable app verification.
let settings = AuthSettings()
Expand Down Expand Up @@ -1095,5 +1101,18 @@
"://firebaseauth/" +
"link?deep_link_id=https%3A%2F%2Fexample.firebaseapp.com%2F__%2Fauth%2Fcallback%3FauthType%" +
"3DverifyApp%26recaptchaToken%3DfakeReCAPTCHAToken"

func testVerifyPhoneNumberWithAppCheckError() async throws {
let fakeAppCheck = FakeAppCheck()
let expectedError = NSError(domain: "appCheckError", code: -1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low

For improved maintainability and to avoid magic strings, consider defining "appCheckError" and -1 as private constants at the top of the PhoneAuthProviderTests class. This makes the test code cleaner and easier to manage if these values are reused.

fakeAppCheck.error = expectedError
try await internalTestVerify(
errorCode: expectedError.code,
function: #function,
reCAPTCHAfallback: true,
presenterError: nil,
fakeAppCheck: fakeAppCheck
)
}
}
#endif
Loading