Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
2 changes: 1 addition & 1 deletion FirebaseAuth.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ supports email and password accounts, as well as several 3rd party authenticatio
s.dependency 'GoogleUtilities/AppDelegateSwizzler', '~> 8.0'
s.dependency 'GoogleUtilities/Environment', '~> 8.0'
s.dependency 'GTMSessionFetcher/Core', '>= 3.4', '< 5.0'
s.ios.dependency 'RecaptchaInterop', '~> 100.0'
s.ios.dependency 'RecaptchaInterop', '~> 101.0'
s.test_spec 'unit' do |unit_tests|
unit_tests.scheme = { :code_coverage => true }
# Unit tests can't run on watchOS.
Expand Down
4 changes: 4 additions & 0 deletions FirebaseAuth/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Unreleased
- [changed] Using reCAPTCHA Enterprise and Firebase Auth requires reCAPTCHA
Enterprise X.Y.Z or later.

# 11.6.0
- [added] Added reCAPTCHA Enterprise support for app verification during phone
authentication for Firebase Authentication (#14114)
Expand Down
88 changes: 0 additions & 88 deletions FirebaseAuth/Sources/ObjC/FIRRecaptchaBridge.m

This file was deleted.

33 changes: 0 additions & 33 deletions FirebaseAuth/Sources/Public/FirebaseAuth/FIRRecaptchaBridge.h

This file was deleted.

1 change: 0 additions & 1 deletion FirebaseAuth/Sources/Public/FirebaseAuth/FirebaseAuth.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,4 @@
#import "FIRGoogleAuthProvider.h"
#import "FIRMultiFactor.h"
#import "FIRPhoneAuthProvider.h"
#import "FIRRecaptchaBridge.h"
#import "FIRTwitterAuthProvider.h"
93 changes: 65 additions & 28 deletions FirebaseAuth/Sources/Swift/Utilities/AuthRecaptchaVerifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,38 +125,75 @@
// No recaptcha on internal build system.
return actionString
#else
return try await withCheckedThrowingContinuation { continuation in
FIRRecaptchaGetToken(siteKey, actionString,
"NO_RECAPTCHA") { (token: String, error: Error?,
linked: Bool, actionCreated: Bool) in
guard linked else {
continuation.resume(throwing: AuthErrorUtils.recaptchaSDKNotLinkedError())
return
}
guard actionCreated else {
continuation.resume(throwing: AuthErrorUtils.recaptchaActionCreationFailed())
return
}
if let error {
continuation.resume(throwing: error)
return
} else {
if token == "NO_RECAPTCHA" {
AuthLog.logInfo(code: "I-AUT000031",
message: "reCAPTCHA token retrieval failed. NO_RECAPTCHA sent as the fake code.")
} else {
AuthLog.logInfo(
code: "I-AUT000030",
message: "reCAPTCHA token retrieval succeeded."
)
}
continuation.resume(returning: token)
}
}

let (token, error, linked, actionCreated) = await recaptchaToken(
siteKey: siteKey,
actionString: actionString,
fakeToken: "NO_RECAPTCHA"
)

guard linked else {
throw AuthErrorUtils.recaptchaSDKNotLinkedError()
}
guard actionCreated else {
throw AuthErrorUtils.recaptchaActionCreationFailed()
}
if let error {
throw error
}
if token == "NO_RECAPTCHA" {
AuthLog.logInfo(code: "I-AUT000031",
message: "reCAPTCHA token retrieval failed. NO_RECAPTCHA sent as the fake code.")
} else {
AuthLog.logInfo(
code: "I-AUT000030",
message: "reCAPTCHA token retrieval succeeded."
)
}
return token
#endif // !(COCOAPODS || SWIFT_PACKAGE)
}

private static var recaptchaClient: (any RCARecaptchaClientProtocol)?

private func recaptchaToken(siteKey: String,
actionString: String,
fakeToken: String) async -> (token: String, error: Error?,
linked: Bool, actionCreated: Bool) {
if recaptchaClient != nil {
return await retrieveToken(actionString: actionString, fakeToken: fakeToken)
}

if let recaptcha =
NSClassFromString("RecaptchaEnterprise.RCARecaptcha") as? RCARecaptchaProtocol.Type {
do {
// TODO(ncooke3): This should be `fetchClient(withSiteKey:)`.
let client = try await recaptcha.getClient(withSiteKey: siteKey)
recaptchaClient = client
return await retrieveToken(actionString: actionString, fakeToken: fakeToken)
} catch {
return ("", error, true, true)
}
} else {
// RecaptchaEnterprise not linked.
return ("", nil, false, false)
}
}

private func retrieveToken(actionString: String,
fakeToken: String) async -> (token: String, error: Error?,
linked: Bool, actionCreated: Bool) {
if let recaptchaAction =
NSClassFromString("RecaptchaEnterprise.RCAAction") as? RCAActionProtocol.Type {
let action = recaptchaAction.init(customAction: actionString)
let token = try? await recaptchaClient!.execute(withAction: action)
return (token ?? "NO_RECAPTCHA", nil, true, true)
} else {
// RecaptchaEnterprise not linked.
return ("", nil, false, false)
}
}

func retrieveRecaptchaConfig(forceRefresh: Bool) async throws {
if !forceRefresh {
if let tenantID = auth?.tenantID {
Expand Down
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ let package = Package(
.package(
url: "https://github.com/google/interop-ios-for-google-sdks.git",
"100.0.0" ..< "101.0.0"
// "101.0.0" ..< "102.0.0"
),
.package(url: "https://github.com/google/app-check.git",
"11.0.1" ..< "12.0.0"),
Expand Down
Loading