Skip to content

Commit 9f6f969

Browse files
committed
handles unstructured errors on redirect URLs
1 parent b561342 commit 9f6f969

File tree

4 files changed

+78
-2
lines changed

4 files changed

+78
-2
lines changed

Example/Auth/Tests/FIRPhoneAuthProviderTests.m

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@
162162
"0invalid%2520or%2520does%2520not%2520match%2520the%2520specified%2520API%2520key.%2522%257D%26"
163163
"authType%3DverifyApp";
164164

165+
/** @var kFakeRedirectURLStringUnstructuredError
166+
@brief The format for a fake redirect URL string with unstructured error response.
167+
*/
168+
static NSString *const kFakeRedirectURLStringUnstructuredError = @"com.googleusercontent.apps.1"
169+
"23456://firebaseauth/link?deep_link_id=https%3A%2F%2Fexample.firebaseapp.com%2F__%2Fauth%2Fcal"
170+
"lback%3FfirebaseError%3D%257B%2522unstructuredcode%2522%253A%2522auth%252Funknown-error-id%2522%252"
171+
"C%2522unstructuredmessage%2522%253A%2522The%2520OAuth%2520client%2520ID%2520provided%2520is%2520either%252"
172+
"0invalid%2520or%2520does%2520not%2520match%2520the%2520specified%2520API%2520key.%2522%257D%26"
173+
"authType%3DverifyApp";
174+
165175
/** @var kTestTimeout
166176
@brief A fake timeout value for waiting for push notification.
167177
*/
@@ -721,6 +731,70 @@ - (void)testVerifyPhoneNumberUIDelegateUnexpectedError {
721731
OCMVerifyAll(_mockNotificationManager);
722732
}
723733

734+
/** @fn testVerifyPhoneNumberUIDelegateUnstructuredError
735+
@brief Tests a invocation of @c verifyPhoneNumber:UIDelegate:completion: which results in an
736+
invalid client ID.
737+
*/
738+
- (void)testVerifyPhoneNumberUIDelegateUnstructuredError {
739+
id mockBundle = OCMClassMock([NSBundle class]);
740+
OCMStub(ClassMethod([mockBundle mainBundle])).andReturn(mockBundle);
741+
OCMStub([mockBundle objectForInfoDictionaryKey:@"CFBundleURLTypes"])
742+
.andReturn(@[ @{ @"CFBundleURLSchemes" : @[ kFakeReverseClientID ] } ]);
743+
OCMStub([mockBundle bundleIdentifier]).andReturn(kFakeBundleID);
744+
745+
// Simulate missing app token error.
746+
OCMExpect([_mockNotificationManager checkNotificationForwardingWithCallback:OCMOCK_ANY])
747+
.andCallBlock1(^(FIRAuthNotificationForwardingCallback callback) { callback(YES); });
748+
OCMExpect([_mockAppCredentialManager credential]).andReturn(nil);
749+
OCMExpect([_mockAPNSTokenManager getTokenWithCallback:OCMOCK_ANY])
750+
.andCallBlock1(^(FIRAuthAPNSTokenCallback callback) {
751+
NSError *error = [NSError errorWithDomain:FIRAuthErrorDomain
752+
code:FIRAuthErrorCodeMissingAppToken
753+
userInfo:nil];
754+
callback(nil, error);
755+
});
756+
OCMExpect([_mockBackend getProjectConfig:[OCMArg any] callback:[OCMArg any]])
757+
.andCallBlock2(^(FIRGetProjectConfigRequest *request,
758+
FIRGetProjectConfigResponseCallback callback) {
759+
XCTAssertNotNil(request);
760+
dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
761+
id mockGetProjectConfigResponse = OCMClassMock([FIRGetProjectConfigResponse class]);
762+
OCMStub([mockGetProjectConfigResponse authorizedDomains]).
763+
andReturn(@[ kFakeAuthorizedDomain]);
764+
callback(mockGetProjectConfigResponse, nil);
765+
});
766+
});
767+
id mockUIDelegate = OCMProtocolMock(@protocol(FIRAuthUIDelegate));
768+
769+
// Expect view controller presentation by UIDelegate.
770+
OCMExpect([_mockURLPresenter presentURL:OCMOCK_ANY
771+
UIDelegate:mockUIDelegate
772+
callbackMatcher:OCMOCK_ANY
773+
completion:OCMOCK_ANY]).andDo(^(NSInvocation *invocation) {
774+
__unsafe_unretained id unretainedArgument;
775+
// Indices 0 and 1 indicate the hidden arguments self and _cmd.
776+
// `completion` is at index 5
777+
[invocation getArgument:&unretainedArgument atIndex:5];
778+
FIRAuthURLPresentationCompletion completion = unretainedArgument;
779+
dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
780+
completion([NSURL URLWithString:kFakeRedirectURLStringUnstructuredError], nil);
781+
});
782+
});
783+
784+
XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
785+
[_provider verifyPhoneNumber:kTestPhoneNumber
786+
UIDelegate:mockUIDelegate
787+
completion:^(NSString *_Nullable verificationID, NSError *_Nullable error) {
788+
XCTAssertTrue([NSThread isMainThread]);
789+
XCTAssertEqual(error.code, FIRAuthErrorCodeAppVerificationUserInteractionFailure);
790+
XCTAssertNil(verificationID);
791+
[expectation fulfill];
792+
}];
793+
[self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
794+
OCMVerifyAll(_mockBackend);
795+
OCMVerifyAll(_mockNotificationManager);
796+
}
797+
724798
/** @fn testVerifyPhoneNumberUIDelegateRaiseException
725799
@brief Tests a invocation of @c verifyPhoneNumber:UIDelegate:completion: which results in an
726800
exception.

Firebase/Auth/Source/AuthProviders/Phone/FIRPhoneAuthProvider.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ - (NSString *)reCAPTCHATokenForURL:(NSURL *)URL error:(NSError **)error {
266266
NSString *reason;
267267
if(errorDict[@"code"] && errorDict[@"message"]) {
268268
reason = [NSString stringWithFormat:@"[%@] - %@",errorDict[@"code"], errorDict[@"message"]];
269+
} else {
270+
reason = @"An unknown error has occurred";
269271
}
270272
*error = [FIRAuthErrorUtils appVerificationUserInteractionFailureWithReason:reason];
271273
}

Firebase/Auth/Source/FIRAuthErrorUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ NS_ASSUME_NONNULL_BEGIN
472472
@param reason Reason for error, returned via URL response.
473473
@return The NSError instance associated with the given FIRAuthError.
474474
*/
475-
+ (NSError *)appVerificationUserInteractionFailureWithReason:(nullable NSString *)reason;
475+
+ (NSError *)appVerificationUserInteractionFailureWithReason:(NSString *)reason;
476476

477477
/** @fn URLResponseErrorWithCode:message:
478478
@brief Constructs an @c NSError with the code and message provided.

Firebase/Auth/Source/FIRAuthErrorUtils.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ + (NSError *)webContextCancelledErrorWithMessage:(nullable NSString *)message {
961961
return [self errorWithCode:FIRAuthInternalErrorCodeWebContextCancelled message:message];
962962
}
963963

964-
+ (NSError *)appVerificationUserInteractionFailureWithReason:(nullable NSString *)reason {
964+
+ (NSError *)appVerificationUserInteractionFailureWithReason:(NSString *)reason {
965965
return [self errorWithCode:FIRAuthInternalErrorCodeAppVerificationUserInteractionFailure
966966
userInfo:@{
967967
NSLocalizedFailureReasonErrorKey : reason

0 commit comments

Comments
 (0)