From bc1afe747360ca8987353c78eff8674c27ee0e71 Mon Sep 17 00:00:00 2001 From: Chuan Ren Date: Wed, 12 Sep 2018 14:03:57 -0700 Subject: [PATCH 1/3] Add supporting of custom fdl domain --- .../Tests/FIRGetOOBConfirmationCodeRequestTests.m | 14 ++++++++++++++ Firebase/Auth/Source/FIRAuthErrorUtils.h | 7 +++++++ Firebase/Auth/Source/FIRAuthErrorUtils.m | 15 +++++++++++++++ Firebase/Auth/Source/FIRAuthInternalErrors.h | 6 ++++++ .../Auth/Source/Public/FIRActionCodeSettings.h | 5 +++++ Firebase/Auth/Source/Public/FIRAuthErrors.h | 5 +++++ .../RPCs/FIRGetOOBConfirmationCodeRequest.h | 6 ++++++ .../RPCs/FIRGetOOBConfirmationCodeRequest.m | 10 ++++++++++ 8 files changed, 68 insertions(+) diff --git a/Example/Auth/Tests/FIRGetOOBConfirmationCodeRequestTests.m b/Example/Auth/Tests/FIRGetOOBConfirmationCodeRequestTests.m index b11c7599b3d..4d539c5d336 100644 --- a/Example/Auth/Tests/FIRGetOOBConfirmationCodeRequestTests.m +++ b/Example/Auth/Tests/FIRGetOOBConfirmationCodeRequestTests.m @@ -126,6 +126,16 @@ */ static NSString *const kCanHandleCodeInAppKey = @"canHandleCodeInApp"; +/** @var kDynamicLinkDomainKey + @brief The key for the "dynamic link domain" value in the request. + */ +static NSString *const kDynamicLinkDomainKey = @"dynamicLinkDomain"; + +/** @var kDynamicLinkDomain + @brief Fake dynamic link domain for testing. + */ +static NSString *const kDynamicLinkDomain = @"test.page.link"; + /** @class FIRGetOOBConfirmationCodeRequestTests @brief Tests for @c FIRGetOOBConfirmationCodeRequest. */ @@ -194,6 +204,7 @@ - (void)testPasswordResetRequest { [NSNumber numberWithBool:YES]); XCTAssertEqualObjects(_RPCIssuer.decodedRequest[kCanHandleCodeInAppKey], [NSNumber numberWithBool:YES]); + XCTAssertEqualObjects(_RPCIssuer.decodedRequest[kDynamicLinkDomainKey], kDynamicLinkDomain); } /** @fn testSignInWithEmailLinkRequest @@ -230,6 +241,7 @@ - (void)testSignInWithEmailLinkRequest { [NSNumber numberWithBool:YES]); XCTAssertEqualObjects(_RPCIssuer.decodedRequest[kCanHandleCodeInAppKey], [NSNumber numberWithBool:YES]); + XCTAssertEqualObjects(_RPCIssuer.decodedRequest[kDynamicLinkDomainKey], kDynamicLinkDomain); } @@ -268,6 +280,7 @@ - (void)testEmailVerificationRequest { [NSNumber numberWithBool:YES]); XCTAssertEqualObjects(_RPCIssuer.decodedRequest[kCanHandleCodeInAppKey], [NSNumber numberWithBool:YES]); + XCTAssertEqualObjects(_RPCIssuer.decodedRequest[kDynamicLinkDomainKey], kDynamicLinkDomain); } #pragma mark - Helpers @@ -284,6 +297,7 @@ - (FIRActionCodeSettings *)fakeActionCodeSettings { minimumVersion:kAndroidMinimumVersion]; actionCodeSettings.handleCodeInApp = YES; actionCodeSettings.URL = [NSURL URLWithString:kContinueURL]; + actionCodeSettings.dynamicLinkDomain = kDynamicLinkDomain; return actionCodeSettings; } diff --git a/Firebase/Auth/Source/FIRAuthErrorUtils.h b/Firebase/Auth/Source/FIRAuthErrorUtils.h index c21c2b81178..6fa276c6523 100644 --- a/Firebase/Auth/Source/FIRAuthErrorUtils.h +++ b/Firebase/Auth/Source/FIRAuthErrorUtils.h @@ -501,6 +501,13 @@ NS_ASSUME_NONNULL_BEGIN */ + (NSError *)nullUserErrorWithMessage:(nullable NSString *)message; +/** @fn invalidDynamicLinkDomainErrorWithMessage: + @brief Constructs an @c NSError with the code and message provided. + @param message Error message from the backend, if any. + @return The nullable NSError instance associated with the given error message, if one is found. + */ ++ (NSError *)invalidDynamicLinkDomainErrorWithMessage:(nullable NSString *)message; + /** @fn keychainErrorWithFunction:status: @brief Constructs an @c NSError with the @c FIRAuthErrorCodeKeychainError code. @param keychainFunction The keychain function which was invoked and yielded an unexpected diff --git a/Firebase/Auth/Source/FIRAuthErrorUtils.m b/Firebase/Auth/Source/FIRAuthErrorUtils.m index 2e7761d3518..0defad1d481 100644 --- a/Firebase/Auth/Source/FIRAuthErrorUtils.m +++ b/Firebase/Auth/Source/FIRAuthErrorUtils.m @@ -407,6 +407,13 @@ static NSString *const kFIRAuthErrorMessageNullUser = @"A null user object was provided as the " "argument for an operation which requires a non-null user object."; +/** @var kFIRAuthErrorMessageInvalidDynamicLinkDomain + @brief Message for @c kFIRAuthErrorMessageInvalidDynamicLinkDomain error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidDynamicLinkDomain = @"The" + "Firebase Dynamic Link domain used is either not configured or is unauthorized" + "for the current project."; + /** @var kFIRAuthErrorMessageInternalError @brief Message for @c FIRAuthErrorCodeInternalError error code. */ @@ -535,6 +542,8 @@ return kFIRAuthErrorMessageWebRequestFailed; case FIRAuthErrorCodeNullUser: return kFIRAuthErrorMessageNullUser; + case FIRAuthErrorCodeInvalidDynamicLinkDomain: + return kFIRAuthErrorMessageInvalidDynamicLinkDomain; case FIRAuthErrorCodeWebInternalError: return kFIRAuthErrorMessageWebInternalError; case FIRAuthErrorCodeMalformedJWT: @@ -658,6 +667,8 @@ return @"ERROR_WEB_NETWORK_REQUEST_FAILED"; case FIRAuthErrorCodeNullUser: return @"ERROR_NULL_USER"; + case FIRAuthErrorCodeInvalidDynamicLinkDomain: + return @"ERROR_INVALID_DYNAMIC_LINK_DOMAIN"; case FIRAuthErrorCodeWebInternalError: return @"ERROR_WEB_INTERNAL_ERROR"; case FIRAuthErrorCodeMalformedJWT: @@ -1019,6 +1030,10 @@ + (NSError *)nullUserErrorWithMessage:(nullable NSString *)message { return [self errorWithCode:FIRAuthInternalErrorCodeNullUser message:message]; } ++ (NSError *)invalidDynamicLinkDomainErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidDynamicLinkDomain message:message]; +} + + (NSError *)keychainErrorWithFunction:(NSString *)keychainFunction status:(OSStatus)status { NSString *failureReason = [NSString stringWithFormat:@"%@ (%li)", keychainFunction, (long)status]; return [self errorWithCode:FIRAuthInternalErrorCodeKeychainError userInfo:@{ diff --git a/Firebase/Auth/Source/FIRAuthInternalErrors.h b/Firebase/Auth/Source/FIRAuthInternalErrors.h index 4cdd8cf6715..5fa9f18c3b4 100644 --- a/Firebase/Auth/Source/FIRAuthInternalErrors.h +++ b/Firebase/Auth/Source/FIRAuthInternalErrors.h @@ -376,6 +376,12 @@ typedef NS_ENUM(NSInteger, FIRAuthInternalErrorCode) { FIRAuthInternalErrorCodeNullUser = FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeNullUser, + /** Indicates that the Firebase Dynamic Link domain used is either not configured or is unauthorized + for the current project. + */ + FIRAuthInternalErrorCodeInvalidDynamicLinkDomain = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidDynamicLinkDomain, + FIRAuthInternalErrorCodeMalformedJWT = FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMalformedJWT, diff --git a/Firebase/Auth/Source/Public/FIRActionCodeSettings.h b/Firebase/Auth/Source/Public/FIRActionCodeSettings.h index 6eb4c89d999..788e0609907 100644 --- a/Firebase/Auth/Source/Public/FIRActionCodeSettings.h +++ b/Firebase/Auth/Source/Public/FIRActionCodeSettings.h @@ -59,6 +59,11 @@ */ @property(nonatomic, assign, readonly) BOOL androidInstallIfNotAvailable; + /** @property dynamicLinkDomain + @brief The Firebase Dynamic Link domain used for out of band code flow. + */ + @property (copy, nonatomic, nullable) NSString *dynamicLinkDomain; + /** @fn setIOSBundleID @brief Sets the iOS bundle Id. @param iOSBundleID The iOS bundle ID. diff --git a/Firebase/Auth/Source/Public/FIRAuthErrors.h b/Firebase/Auth/Source/Public/FIRAuthErrors.h index a3fbe26a3ec..796c01314da 100644 --- a/Firebase/Auth/Source/Public/FIRAuthErrors.h +++ b/Firebase/Auth/Source/Public/FIRAuthErrors.h @@ -304,6 +304,11 @@ typedef NS_ENUM(NSInteger, FIRAuthErrorCode) { */ FIRAuthErrorCodeNullUser = 17067, + /** Indicates that the Firebase Dynamic Link domain used is either not configured or is unauthorized + for the current project. + */ + FIRAuthErrorCodeInvalidDynamicLinkDomain = 17074, + /** Indicates an error occurred while attempting to access the keychain. */ FIRAuthErrorCodeKeychainError = 17995, diff --git a/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.h b/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.h index 751cfe79ca3..3130c7898fb 100644 --- a/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.h +++ b/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.h @@ -96,6 +96,12 @@ typedef NS_ENUM(NSInteger, FIRGetOOBConfirmationCodeRequestType) { */ @property(assign, nonatomic) BOOL handleCodeInApp; +/** @property dynamicLinkDomain + @brief The Firebase Dynamic Link domain used for out of band code flow. + */ +@property (copy, nonatomic, nullable) NSString *dynamicLinkDomain; + + /** @fn passwordResetRequestWithEmail:actionCodeSettings:requestConfiguration: @brief Creates a password reset request. @param email The user's email address. diff --git a/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.m b/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.m index 438f24b720d..82f1a271fa8 100644 --- a/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.m +++ b/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.m @@ -74,6 +74,11 @@ */ static NSString *const kCanHandleCodeInAppKey = @"canHandleCodeInApp"; +/** @var kDynamicLinkDomainKey + @brief The key for the "dynamic link domain" value in the request. + */ +static NSString *const kDynamicLinkDomainKey = @"dynamicLinkDomain"; + /** @var kPasswordResetRequestTypeValue @brief The value for the "PASSWORD_RESET" request type. */ @@ -177,6 +182,7 @@ - (nullable instancetype)initWithRequestType:(FIRGetOOBConfirmationCodeRequestTy _androidMinimumVersion = actionCodeSettings.androidMinimumVersion; _androidInstallApp = actionCodeSettings.androidInstallIfNotAvailable; _handleCodeInApp = actionCodeSettings.handleCodeInApp; + _dynamicLinkDomain = actionCodeSettings.dynamicLinkDomain; } return self; } @@ -228,6 +234,10 @@ - (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable) body[kCanHandleCodeInAppKey] = @YES; } + if (_dynamicLinkDomain) { + body[kDynamicLinkDomainKey] = _dynamicLinkDomain; + } + return body; } From d6c16ecfd135ca27b99faa34e17b6286cc6154fa Mon Sep 17 00:00:00 2001 From: Chuan Ren Date: Wed, 12 Sep 2018 16:32:57 -0700 Subject: [PATCH 2/3] Add spaces between concatenated strings --- Firebase/Auth/Source/FIRAuthErrorUtils.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firebase/Auth/Source/FIRAuthErrorUtils.m b/Firebase/Auth/Source/FIRAuthErrorUtils.m index 0defad1d481..bd518799951 100644 --- a/Firebase/Auth/Source/FIRAuthErrorUtils.m +++ b/Firebase/Auth/Source/FIRAuthErrorUtils.m @@ -410,8 +410,8 @@ /** @var kFIRAuthErrorMessageInvalidDynamicLinkDomain @brief Message for @c kFIRAuthErrorMessageInvalidDynamicLinkDomain error code. */ -static NSString *const kFIRAuthErrorMessageInvalidDynamicLinkDomain = @"The" - "Firebase Dynamic Link domain used is either not configured or is unauthorized" +static NSString *const kFIRAuthErrorMessageInvalidDynamicLinkDomain = @"The " + "Firebase Dynamic Link domain used is either not configured or is unauthorized " "for the current project."; /** @var kFIRAuthErrorMessageInternalError From 5fa95a98c2944e967e853a9f187ab6f2a72c6883 Mon Sep 17 00:00:00 2001 From: Chuan Ren Date: Thu, 13 Sep 2018 17:40:29 -0700 Subject: [PATCH 3/3] Client should create NSError based on server message --- Firebase/Auth/Source/RPCs/FIRAuthBackend.m | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Firebase/Auth/Source/RPCs/FIRAuthBackend.m b/Firebase/Auth/Source/RPCs/FIRAuthBackend.m index 4bbf1678c30..3bdb0f97ad2 100644 --- a/Firebase/Auth/Source/RPCs/FIRAuthBackend.m +++ b/Firebase/Auth/Source/RPCs/FIRAuthBackend.m @@ -284,6 +284,12 @@ */ static NSString *const kUnauthorizedDomainErrorMessage = @"UNAUTHORIZED_DOMAIN"; +/** @var kInvalidDynamicLinkDomainErrorMessage + @brief This is the error message the server will respond with if the dynamic link domain provided + in the request is invalid. + */ +static NSString *const kInvalidDynamicLinkDomainErrorMessage = @"INVALID_DYNAMIC_LINK_DOMAIN"; + /** @var kInvalidContinueURIErrorMessage @brief This is the error message the server will respond with if the continue URL provided in the request is invalid. @@ -1044,6 +1050,10 @@ + (nullable NSError *)clientErrorWithServerErrorMessage:(NSString *)serverErrorM return [FIRAuthErrorUtils invalidContinueURIErrorWithMessage:serverDetailErrorMessage]; } + if ([shortErrorMessage isEqualToString:kInvalidDynamicLinkDomainErrorMessage]) { + return [FIRAuthErrorUtils invalidDynamicLinkDomainErrorWithMessage:serverDetailErrorMessage]; + } + if ([shortErrorMessage isEqualToString:kMissingContinueURIErrorMessage]) { return [FIRAuthErrorUtils missingContinueURIErrorWithMessage:serverDetailErrorMessage]; }