feat: Add Recaptcha attestation provider (#94)

Signed-off-by: Nick Cooke <36927374+ncooke3@users.noreply.github.com>
Co-authored-by: Hitesh Maurya <hiteshmaurya@google.com>
Co-authored-by: Paul Beusterien <paulbeusterien@google.com>
This commit is contained in:
authored and GitHub committed 2026-06-09 16:44:19 -04:00
1 parent f50adb523d
commit f6b4582ed1
57 files changed
+1869 -272

No files matched your search

@@ -18,7 +18,7 @@
@class FBLPromise<Result>;
@class GACAppCheckToken;
@protocol GACAppCheckAPIServiceProtocol;
@protocol _GACAppCheckAPIServiceProtocol;
NS_ASSUME_NONNULL_BEGIN
@@ -32,12 +32,12 @@ NS_ASSUME_NONNULL_BEGIN
@interface GACDeviceCheckAPIService : NSObject <GACDeviceCheckAPIServiceProtocol>
/// Default initializer.
/// @param APIService An instance implementing `GACAppCheckAPIServiceProtocol` to be used to send
/// @param APIService An instance implementing `_GACAppCheckAPIServiceProtocol` to be used to send
/// network requests to the App Check backend.
/// @param resourceName The name of the resource protected by App Check; for a Firebase App this is
/// "projects/{project_id}/apps/{app_id}". See https://google.aip.dev/122 for more details about
/// resource names.
- (instancetype)initWithAPIService:(id<GACAppCheckAPIServiceProtocol>)APIService
- (instancetype)initWithAPIService:(id<_GACAppCheckAPIServiceProtocol>)APIService
resourceName:(NSString *)resourceName;
@end
@@ -22,11 +22,11 @@
#import "FBLPromises.h"
#endif
#import "AppCheckCore/Sources/Core/APIService/GACAppCheckAPIService.h"
#import "AppCheckCore/Sources/Core/APIService/GACAppCheckToken+APIResponse.h"
#import "AppCheckCore/Sources/Public/AppCheckCore/_GACAppCheckAPIService.h"
#import "AppCheckCore/Sources/Core/Errors/GACAppCheckErrorUtil.h"
#import "AppCheckCore/Sources/Core/GACAppCheckLogger+Internal.h"
#import "AppCheckCore/Sources/Public/AppCheckCore/_GACAppCheckErrorUtil.h"
NS_ASSUME_NONNULL_BEGIN
@@ -37,7 +37,7 @@ static NSString *const kLimitedUseField = @"limited_use";
@interface GACDeviceCheckAPIService ()
@property(nonatomic, readonly) id<GACAppCheckAPIServiceProtocol> APIService;
@property(nonatomic, readonly) id<_GACAppCheckAPIServiceProtocol> APIService;
@property(nonatomic, readonly) NSString *resourceName;
@@ -45,7 +45,7 @@ static NSString *const kLimitedUseField = @"limited_use";
@implementation GACDeviceCheckAPIService
- (instancetype)initWithAPIService:(id<GACAppCheckAPIServiceProtocol>)APIService
- (instancetype)initWithAPIService:(id<_GACAppCheckAPIServiceProtocol>)APIService
resourceName:(NSString *)resourceName {
self = [super init];
if (self) {
@@ -64,13 +64,13 @@ static NSString *const kLimitedUseField = @"limited_use";
NSURL *URL = [NSURL URLWithString:URLString];
return [self HTTPBodyWithDeviceToken:deviceToken limitedUse:limitedUse]
.then(^FBLPromise<GACURLSessionDataResponse *> *(NSData *HTTPBody) {
.then(^FBLPromise<_GACURLSessionDataResponse *> *(NSData *HTTPBody) {
return [self.APIService sendRequestWithURL:URL
HTTPMethod:@"POST"
body:HTTPBody
additionalHeaders:@{kContentTypeKey : kJSONContentType}];
})
.then(^id _Nullable(GACURLSessionDataResponse *_Nullable response) {
.then(^id _Nullable(_GACURLSessionDataResponse *_Nullable response) {
return [self.APIService appCheckTokenWithAPIResponse:response];
});
}
@@ -79,7 +79,7 @@ static NSString *const kLimitedUseField = @"limited_use";
limitedUse:(BOOL)limitedUse {
if (deviceToken.length <= 0) {
FBLPromise *rejectedPromise = [FBLPromise pendingPromise];
[rejectedPromise reject:[GACAppCheckErrorUtil
[rejectedPromise reject:[_GACAppCheckErrorUtil
errorWithFailureReason:@"DeviceCheck token must not be empty."]];
return rejectedPromise;
}
@@ -100,7 +100,7 @@ static NSString *const kLimitedUseField = @"limited_use";
if (payloadJSON != nil) {
return payloadJSON;
} else {
return [GACAppCheckErrorUtil JSONSerializationError:encodingError];
return [_GACAppCheckErrorUtil JSONSerializationError:encodingError];
}
}];
}
@@ -26,24 +26,24 @@
#import "AppCheckCore/Sources/Public/AppCheckCore/GACDeviceCheckProvider.h"
#import "AppCheckCore/Sources/Core/APIService/GACAppCheckAPIService.h"
#import "AppCheckCore/Sources/Core/Backoff/GACAppCheckBackoffWrapper.h"
#import "AppCheckCore/Sources/Core/Errors/GACAppCheckErrorUtil.h"
#import "AppCheckCore/Sources/Core/GACAppCheckLogger+Internal.h"
#import "AppCheckCore/Sources/DeviceCheckProvider/API/GACDeviceCheckAPIService.h"
#import "AppCheckCore/Sources/DeviceCheckProvider/DCDevice+GACDeviceCheckTokenGenerator.h"
#import "AppCheckCore/Sources/Public/AppCheckCore/GACAppCheckToken.h"
#import "AppCheckCore/Sources/Public/AppCheckCore/_GACAppCheckAPIService.h"
#import "AppCheckCore/Sources/Public/AppCheckCore/_GACAppCheckBackoffWrapper.h"
#import "AppCheckCore/Sources/Public/AppCheckCore/_GACAppCheckErrorUtil.h"
NS_ASSUME_NONNULL_BEGIN
@interface GACDeviceCheckProvider ()
@property(nonatomic, readonly) id<GACDeviceCheckAPIServiceProtocol> APIService;
@property(nonatomic, readonly) id<GACDeviceCheckTokenGenerator> deviceTokenGenerator;
@property(nonatomic, readonly) id<GACAppCheckBackoffWrapperProtocol> backoffWrapper;
@property(nonatomic, readonly) id<_GACAppCheckBackoffWrapperProtocol> backoffWrapper;
- (instancetype)initWithAPIService:(id<GACDeviceCheckAPIServiceProtocol>)APIService
deviceTokenGenerator:(id<GACDeviceCheckTokenGenerator>)deviceTokenGenerator
backoffWrapper:(id<GACAppCheckBackoffWrapperProtocol>)backoffWrapper
backoffWrapper:(id<_GACAppCheckBackoffWrapperProtocol>)backoffWrapper
NS_DESIGNATED_INITIALIZER;
@end
@@ -52,7 +52,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithAPIService:(id<GACDeviceCheckAPIServiceProtocol>)APIService
deviceTokenGenerator:(id<GACDeviceCheckTokenGenerator>)deviceTokenGenerator
backoffWrapper:(id<GACAppCheckBackoffWrapperProtocol>)backoffWrapper {
backoffWrapper:(id<_GACAppCheckBackoffWrapperProtocol>)backoffWrapper {
self = [super init];
if (self) {
_APIService = APIService;
@@ -63,7 +63,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (instancetype)initWithAPIService:(id<GACDeviceCheckAPIServiceProtocol>)APIService {
GACAppCheckBackoffWrapper *backoffWrapper = [[GACAppCheckBackoffWrapper alloc] init];
_GACAppCheckBackoffWrapper *backoffWrapper = [[_GACAppCheckBackoffWrapper alloc] init];
return [self initWithAPIService:APIService
deviceTokenGenerator:[DCDevice currentDevice]
backoffWrapper:backoffWrapper];
@@ -76,11 +76,11 @@ NS_ASSUME_NONNULL_BEGIN
NSURLSession *URLSession = [NSURLSession
sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
GACAppCheckAPIService *APIService =
[[GACAppCheckAPIService alloc] initWithURLSession:URLSession
baseURL:nil
APIKey:APIKey
requestHooks:requestHooks];
_GACAppCheckAPIService *APIService =
[[_GACAppCheckAPIService alloc] initWithURLSession:URLSession
baseURL:nil
APIKey:APIKey
requestHooks:requestHooks];
GACDeviceCheckAPIService *deviceCheckAPIService =
[[GACDeviceCheckAPIService alloc] initWithAPIService:APIService resourceName:resourceName];
@@ -146,7 +146,7 @@ NS_ASSUME_NONNULL_BEGIN
if (self.deviceTokenGenerator.isSupported) {
return [FBLPromise resolvedWith:[NSNull null]];
} else {
NSError *error = [GACAppCheckErrorUtil unsupportedAttestationProvider:@"DeviceCheckProvider"];
NSError *error = [_GACAppCheckErrorUtil unsupportedAttestationProvider:@"DeviceCheckProvider"];
FBLPromise *rejectedPromise = [FBLPromise pendingPromise];
[rejectedPromise reject:error];
return rejectedPromise;