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
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,17 @@ - (nullable NSData *)randomChallengeFromResponseBody:(NSData *)response error:(N
body:HTTPBody
additionalHeaders:@{kContentTypeKey : kJSONContentType}];
})
.thenOn(
[self backgroundQueue], ^id _Nullable(_GACURLSessionDataResponse *_Nullable URLResponse) {
NSError *error;
.thenOn([self backgroundQueue],
^id _Nullable(_GACURLSessionDataResponse *_Nullable URLResponse) {
NSError *error;

__auto_type response =
[[GACAppAttestAttestationResponse alloc] initWithResponseData:URLResponse.HTTPBody
requestDate:[NSDate date]
error:&error];
__auto_type response = [[GACAppAttestAttestationResponse alloc]
initWithResponseData:URLResponse.HTTPBody
requestDate:URLResponse.requestDate
error:&error];

return response ?: error;
});
return response ?: error;
});
}

#pragma mark - Request HTTP Body
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ - (instancetype)initWithURLSession:(NSURLSession *)session

GACAppCheckToken *token = [[GACAppCheckToken alloc]
initWithTokenExchangeResponse:response.HTTPBody
requestDate:[NSDate date]
requestDate:response.requestDate
error:&error];
return token ?: error;
}];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@

@implementation _GACURLSessionDataResponse

- (instancetype)initWithResponse:(NSHTTPURLResponse *)response HTTPBody:(NSData *)body {
- (instancetype)initWithResponse:(NSHTTPURLResponse *)response
HTTPBody:(NSData *)body
requestDate:(NSDate *)requestDate {
self = [super init];
if (self) {
_HTTPResponse = response;
_HTTPBody = body;
_requestDate = requestDate;
}
return self;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ @implementation NSURLSession (GACPromises)

- (FBLPromise<_GACURLSessionDataResponse *> *)gac_dataTaskPromiseWithRequest:
(NSURLRequest *)URLRequest {
NSDate *requestDate = [NSDate date];
return [FBLPromise async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {
[[self dataTaskWithRequest:URLRequest
completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response,
Expand All @@ -37,7 +38,8 @@ @implementation NSURLSession (GACPromises)
} else {
fulfill([[_GACURLSessionDataResponse alloc]
initWithResponse:(NSHTTPURLResponse *)response
HTTPBody:data]);
HTTPBody:data
requestDate:requestDate]);
}
}] resume];
}];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ NS_ASSUME_NONNULL_BEGIN

@property(nonatomic, readonly) NSHTTPURLResponse *HTTPResponse;
@property(nonatomic, nullable, readonly) NSData *HTTPBody;
@property(nonatomic, readonly) NSDate *requestDate;

- (instancetype)initWithResponse:(NSHTTPURLResponse *)response HTTPBody:(nullable NSData *)body;
- (instancetype)initWithResponse:(NSHTTPURLResponse *)response
HTTPBody:(nullable NSData *)body
requestDate:(NSDate *)requestDate;

@end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,9 @@ - (_GACURLSessionDataResponse *)APIResponseWithCode:(NSInteger)code
XCTAssertNotNil(responseBody);
NSHTTPURLResponse *HTTPResponse = [GACURLSessionFake HTTPResponseWithCode:code];
_GACURLSessionDataResponse *APIResponse =
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse HTTPBody:responseBody];
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse
HTTPBody:responseBody
requestDate:[NSDate date]];
return APIResponse;
}

Expand Down
46 changes: 42 additions & 4 deletions AppCheckCore/Tests/Unit/Core/GACAppCheckAPIServiceTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,9 @@ - (void)testAppCheckTokenWithAPIResponseValidResponse {
XCTAssertNotNil(responseBody);
NSHTTPURLResponse *HTTPResponse = [GACURLSessionFake HTTPResponseWithCode:200];
_GACURLSessionDataResponse *APIResponse =
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse HTTPBody:responseBody];
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse
HTTPBody:responseBody
requestDate:[NSDate date]];

// 2. Expected result.
NSString *expectedFACToken = @"valid_app_check_token";
Expand All @@ -388,13 +390,45 @@ - (void)testAppCheckTokenWithAPIResponseValidResponse {
precision:10]);
}

- (void)testAppCheckTokenWithAPIResponseUsesRequestDate {
// 1. Prepare input parameters.
NSData *responseBody =
[GACFixtureLoader loadFixtureNamed:@"FACTokenExchangeResponseSuccess.json"];
XCTAssertNotNil(responseBody);
NSHTTPURLResponse *HTTPResponse = [GACURLSessionFake HTTPResponseWithCode:200];
NSDate *requestDate = [NSDate dateWithTimeIntervalSince1970:100000];
_GACURLSessionDataResponse *APIResponse =
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse
HTTPBody:responseBody
requestDate:requestDate];

// 2. Expected result.
NSString *expectedFACToken = @"valid_app_check_token";

// 3. Parse API response.
__auto_type tokenPromise = [self.APIService appCheckTokenWithAPIResponse:APIResponse];

// 4. Verify.
XCTAssert(FBLWaitForPromisesWithTimeout(1));

XCTAssertTrue(tokenPromise.isFulfilled);
XCTAssertNil(tokenPromise.error);

XCTAssertEqualObjects(tokenPromise.value.token, expectedFACToken);

NSDate *expectedExpiration = [requestDate dateByAddingTimeInterval:1800];
XCTAssertEqualObjects(tokenPromise.value.expirationDate, expectedExpiration);
}

- (void)testAppCheckTokenWithAPIResponseInvalidFormat {
// 1. Prepare input parameters.
NSString *responseBodyString = @"Token verification failed.";
NSData *responseBody = [responseBodyString dataUsingEncoding:NSUTF8StringEncoding];
NSHTTPURLResponse *HTTPResponse = [GACURLSessionFake HTTPResponseWithCode:200];
_GACURLSessionDataResponse *APIResponse =
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse HTTPBody:responseBody];
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse
HTTPBody:responseBody
requestDate:[NSDate date]];

// 2. Parse API response.
__auto_type tokenPromise = [self.APIService appCheckTokenWithAPIResponse:APIResponse];
Expand Down Expand Up @@ -429,7 +463,9 @@ - (void)assertMissingFieldErrorWithFixture:(NSString *)fixtureName

NSHTTPURLResponse *HTTPResponse = [GACURLSessionFake HTTPResponseWithCode:200];
_GACURLSessionDataResponse *APIResponse =
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse HTTPBody:missingFiledBody];
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse
HTTPBody:missingFiledBody
requestDate:[NSDate date]];

// 2. Parse API response.
__auto_type tokenPromise = [self.APIService appCheckTokenWithAPIResponse:APIResponse];
Expand Down Expand Up @@ -466,7 +502,9 @@ - (void)stubURLSessionDataTaskPromiseWithResponse:(NSHTTPURLResponse *)HTTPRespo
FBLPromise<_GACURLSessionDataResponse *> *result = [FBLPromise pendingPromise];
if (error == nil) {
_GACURLSessionDataResponse *response =
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse HTTPBody:body];
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse
HTTPBody:body
requestDate:[NSDate date]];
[result fulfill:response];
} else {
[result reject:error];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ - (void)testAppCheckTokenSuccessWithLimitedUse:(BOOL)limitedUse {
NSData *fakeResponseData = [@"fake response" dataUsingEncoding:NSUTF8StringEncoding];
NSHTTPURLResponse *HTTPResponse = [GACURLSessionFake HTTPResponseWithCode:200];
_GACURLSessionDataResponse *APIResponse =
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse HTTPBody:fakeResponseData];
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse
HTTPBody:fakeResponseData
requestDate:[NSDate date]];

self.mockAPIService.sendRequestPromise = [FBLPromise resolvedWith:APIResponse];

Expand Down Expand Up @@ -122,7 +124,9 @@ - (void)testAppCheckTokenResponseParsingError {
NSData *fakeResponseData = [@"fake response" dataUsingEncoding:NSUTF8StringEncoding];
NSHTTPURLResponse *HTTPResponse = [GACURLSessionFake HTTPResponseWithCode:200];
_GACURLSessionDataResponse *APIResponse =
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse HTTPBody:fakeResponseData];
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse
HTTPBody:fakeResponseData
requestDate:[NSDate date]];

self.mockAPIService.sendRequestPromise = [FBLPromise resolvedWith:APIResponse];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ - (void)testAppCheckTokenSuccessWithLimitedUse:(BOOL)limitedUse {

NSHTTPURLResponse *HTTPResponse = [GACURLSessionFake HTTPResponseWithCode:200];
_GACURLSessionDataResponse *APIResponse =
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse HTTPBody:responseBody];
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse
HTTPBody:responseBody
requestDate:[NSDate date]];

self.mockAPIService.sendRequestPromise = [FBLPromise resolvedWith:APIResponse];

Expand Down Expand Up @@ -135,7 +137,9 @@ - (void)testAppCheckTokenResponseParsingError {

NSHTTPURLResponse *HTTPResponse = [GACURLSessionFake HTTPResponseWithCode:200];
_GACURLSessionDataResponse *APIResponse =
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse HTTPBody:responseBody];
[[_GACURLSessionDataResponse alloc] initWithResponse:HTTPResponse
HTTPBody:responseBody
requestDate:[NSDate date]];

self.mockAPIService.sendRequestPromise = [FBLPromise resolvedWith:APIResponse];

Expand Down
3 changes: 2 additions & 1 deletion AppCheckRecaptchaProvider/Tests/MockRecaptchaSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ class MockAppCheckCoreAPIService: NSObject, _GACAppCheckAPIServiceProtocol {
} else {
let response = expectedResponse ?? _GACURLSessionDataResponse(
response: HTTPURLResponse(),
httpBody: Data()
httpBody: Data(),
request: Date()
)
promise.fulfill(response)
}
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Unreleased
- [fixed] Fixed an issue where the time-to-live (TTL) for a cached token was calculated from the
moment the token response was processed locally, rather than when the request was initiated,
which could lead to artificially extended token lifetimes during app suspension.
(https://github.com/firebase/firebase-ios-sdk/issues/16573)

# 11.3.1
- [fixed] Added recovery logic to reset and retry attestation when App Attest
returns `DCErrorUnknownSystemFailure` during assertion
Expand Down
Loading