diff --git a/GoogleSignIn/Sources/GIDSignInInternalOptions.h b/GoogleSignIn/Sources/GIDSignInInternalOptions.h index f1aff409..c722d5d4 100644 --- a/GoogleSignIn/Sources/GIDSignInInternalOptions.h +++ b/GoogleSignIn/Sources/GIDSignInInternalOptions.h @@ -24,6 +24,10 @@ #import "GoogleSignIn/Sources/GIDSignIn_Private.h" +#if TARGET_OS_IOS +#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDVerifyAccountDetail.h" +#endif // TARGET_OS_IOS + @class GIDConfiguration; @class GIDSignInResult; @@ -41,6 +45,11 @@ NS_ASSUME_NONNULL_BEGIN /// Whether the sign-in is an addScopes flow. NO means it is a sign in flow. @property(nonatomic, readonly) BOOL addScopesFlow; +#if TARGET_OS_IOS +/// The user account details the Verify with Google flow will verify +@property(nonatomic, copy, nullable, readonly) NSArray *accountDetailsToVerify; +#endif // TARGET_OS_IOS + /// The extra parameters used in the sign-in URL. @property(nonatomic, readonly, nullable) NSDictionary *extraParams; @@ -58,6 +67,11 @@ NS_ASSUME_NONNULL_BEGIN /// The completion block to be called at the completion of the flow. @property(nonatomic, readonly, nullable) GIDSignInCompletion completion; +#if TARGET_OS_IOS +/// The completion block to be called at the completion of the verify flow. +@property(nonatomic, readonly, nullable) GIDVerifyCompletion verifyCompletion; +#endif // TARGET_OS_IOS + /// The scopes to be used during the flow. @property(nonatomic, copy, nullable) NSArray *scopes; @@ -65,6 +79,15 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic, copy, nullable) NSString *loginHint; /// Creates the default options. +#if TARGET_OS_IOS ++ (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)configuration + presentingViewController:(nullable UIViewController *)presentingViewController + loginHint:(nullable NSString *)loginHint + addScopesFlow:(BOOL)addScopesFlow + accountDetailsToVerify:(NSArray *)accountDetailsToVerify + verifyCompletion:(nullable GIDVerifyCompletion)completion; +#endif // TARGET_OS_IOS + #if TARGET_OS_IOS || TARGET_OS_MACCATALYST + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)configuration presentingViewController:(nullable UIViewController *)presentingViewController @@ -78,7 +101,6 @@ NS_ASSUME_NONNULL_BEGIN addScopesFlow:(BOOL)addScopesFlow scopes:(nullable NSArray *)scopes completion:(nullable GIDSignInCompletion)completion; - #elif TARGET_OS_OSX + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)configuration presentingWindow:(nullable NSWindow *)presentingWindow diff --git a/GoogleSignIn/Sources/GIDSignInInternalOptions.m b/GoogleSignIn/Sources/GIDSignInInternalOptions.m index bfb21643..8be7223a 100644 --- a/GoogleSignIn/Sources/GIDSignInInternalOptions.m +++ b/GoogleSignIn/Sources/GIDSignInInternalOptions.m @@ -25,6 +25,29 @@ NS_ASSUME_NONNULL_BEGIN @implementation GIDSignInInternalOptions + +#if TARGET_OS_IOS ++ (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)configuration + presentingViewController:(nullable UIViewController *)presentingViewController + loginHint:(nullable NSString *)loginHint + addScopesFlow:(BOOL)addScopesFlow + accountDetailsToVerify:(NSArray *)accountDetailsToVerify + verifyCompletion:(nullable GIDVerifyCompletion)completion{ + GIDSignInInternalOptions *options = [[GIDSignInInternalOptions alloc] init]; + if (options) { + options->_interactive = YES; + options->_continuation = NO; + options->_addScopesFlow = addScopesFlow; + options->_configuration = configuration; + options->_presentingViewController = presentingViewController; + options->_loginHint = loginHint; + options->_accountDetailsToVerify = accountDetailsToVerify; + options->_verifyCompletion = completion; + } + return options; +} +#endif // TARGET_OS_IOS + #if TARGET_OS_IOS || TARGET_OS_MACCATALYST + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)configuration presentingViewController:(nullable UIViewController *)presentingViewController diff --git a/GoogleSignIn/Sources/GIDVerifyAccountDetail/Implementations/GIDVerifyAccountDetail.m b/GoogleSignIn/Sources/GIDVerifyAccountDetail/Implementations/GIDVerifyAccountDetail.m index f003ebf6..ef551702 100644 --- a/GoogleSignIn/Sources/GIDVerifyAccountDetail/Implementations/GIDVerifyAccountDetail.m +++ b/GoogleSignIn/Sources/GIDVerifyAccountDetail/Implementations/GIDVerifyAccountDetail.m @@ -19,15 +19,15 @@ #import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDVerifiableAccountDetail.h" #import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDVerifiedAccountDetailResult.h" -@implementation GIDVerifyAccountDetail +#if TARGET_OS_IOS -#if TARGET_OS_IOS || TARGET_OS_MACCATALYST +@implementation GIDVerifyAccountDetail - (void)verifyAccountDetails:(NSArray *)accountDetails presentingViewController:(UIViewController *)presentingViewController completion:(nullable void (^)(GIDVerifiedAccountDetailResult *_Nullable verifyResult, NSError *_Nullable error))completion { - // TODO(#383): Implement this method. + // TODO(#383): Implement this method. } - (void)verifyAccountDetails:(NSArray *)accountDetails @@ -35,7 +35,7 @@ - (void)verifyAccountDetails:(NSArray *)accountDet hint:(nullable NSString *)hint completion:(nullable void (^)(GIDVerifiedAccountDetailResult *_Nullable verifyResult, NSError *_Nullable error))completion { - // TODO(#383): Implement this method. + // TODO(#383): Implement this method. } - (void)verifyAccountDetails:(NSArray *)accountDetails @@ -44,9 +44,9 @@ - (void)verifyAccountDetails:(NSArray *)accountDet additionalScopes:(nullable NSArray *)additionalScopes completion:(nullable void (^)(GIDVerifiedAccountDetailResult *_Nullable verifyResult, NSError *_Nullable error))completion { - // TODO(#383): Implement this method. + // TODO(#383): Implement this method. } -#endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST - @end + +#endif // TARGET_OS_IOS diff --git a/GoogleSignIn/Sources/Public/GoogleSignIn/GIDVerifyAccountDetail.h b/GoogleSignIn/Sources/Public/GoogleSignIn/GIDVerifyAccountDetail.h index 76f86bf6..dca4586e 100644 --- a/GoogleSignIn/Sources/Public/GoogleSignIn/GIDVerifyAccountDetail.h +++ b/GoogleSignIn/Sources/Public/GoogleSignIn/GIDVerifyAccountDetail.h @@ -14,38 +14,42 @@ * limitations under the License. */ -#import #import +#if TARGET_OS_IOS + +#import + #if __has_include() #import #elif __has_include() #import #endif +NS_ASSUME_NONNULL_BEGIN + @class GIDVerifiableAccountDetail; @class GIDVerifiedAccountDetailResult; -NS_ASSUME_NONNULL_BEGIN +/// Represents a completion block that takes a `GIDVerifiedAccountDetailResult` on success or an +/// error if the operation was unsuccessful. +typedef void (^GIDVerifyCompletion)(GIDVerifiedAccountDetailResult *_Nullable verifiedResult, + NSError *_Nullable error); /// This class is used to verify a user's Google account details. @interface GIDVerifyAccountDetail : NSObject -#if TARGET_OS_IOS || TARGET_OS_MACCATALYST - /// Starts an interactive verification flow. /// /// The completion will be called at the end of this process. Any saved verification /// state will be replaced by the result of this flow. /// /// @param accountDetails A list of verifiable account details. -/// @param presentingViewController The view controller used to present `SFSafariViewController` on -/// iOS 9 and 10 and to supply `presentationContextProvider` for `ASWebAuthenticationSession` on -/// iOS 13+. +/// @param presentingViewController The view controller used to present the flow. /// @param completion The optional block called asynchronously on the main queue upon completion. -- (void)verifyAccountDetails:(NSArray *)accountDetails - presentingViewController:(UIViewController *)presentingViewController - completion:(nullable void (^)(GIDVerifiedAccountDetailResult *_Nullable verifyResult, +- (void)verifyAccountDetails:(NSArray *)accountDetails + presentingViewController:(UIViewController *)presentingViewController + completion:(nullable void (^)(GIDVerifiedAccountDetailResult *_Nullable verifyResult, NSError *_Nullable error))completion; /// Starts an interactive verification flow using the provided hint. @@ -54,16 +58,14 @@ NS_ASSUME_NONNULL_BEGIN /// state will be replaced by the result of this flow. /// /// @param accountDetails A list of verifiable account details. -/// @param presentingViewController The view controller used to present `SFSafariViewController` on -/// iOS 9 and 10 and to supply `presentationContextProvider` for `ASWebAuthenticationSession` on -/// iOS 13+. +/// @param presentingViewController The view controller used to present the flow. /// @param hint An optional hint for the authorization server, for example the user's ID or email /// address, to be prefilled if possible. /// @param completion The optional block called asynchronously on the main queue upon completion. -- (void)verifyAccountDetails:(NSArray *)accountDetails - presentingViewController:(UIViewController *)presentingViewController +- (void)verifyAccountDetails:(NSArray *)accountDetails + presentingViewController:(UIViewController *)presentingViewController hint:(nullable NSString *)hint - completion:(nullable void (^)(GIDVerifiedAccountDetailResult *_Nullable verifyResult, + completion:(nullable void (^)(GIDVerifiedAccountDetailResult *_Nullable verifyResult, NSError *_Nullable error))completion; /// Starts an interactive verification flow using the provided hint and additional scopes. @@ -72,21 +74,20 @@ NS_ASSUME_NONNULL_BEGIN /// state will be replaced by the result of this flow. /// /// @param accountDetails A list of verifiable account details. -/// @param presentingViewController The view controller used to present `SFSafariViewController` on -/// iOS 9 and 10. +/// @param presentingViewController The view controller used to present the flow. /// @param hint An optional hint for the authorization server, for example the user's ID or email /// address, to be prefilled if possible. /// @param additionalScopes An optional array of scopes to request in addition to the basic profile scopes. /// @param completion The optional block called asynchronously on the main queue upon completion. -- (void)verifyAccountDetails:(NSArray *)accountDetails - presentingViewController:(UIViewController *)presentingViewController +- (void)verifyAccountDetails:(NSArray *)accountDetails + presentingViewController:(UIViewController *)presentingViewController hint:(nullable NSString *)hint additionalScopes:(nullable NSArray *)additionalScopes - completion:(nullable void (^)(GIDVerifiedAccountDetailResult *_Nullable verifyResult, + completion:(nullable void (^)(GIDVerifiedAccountDetailResult *_Nullable verifyResult, NSError *_Nullable error))completion; -#endif - @end NS_ASSUME_NONNULL_END + +#endif // TARGET_OS_IOS diff --git a/GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m b/GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m index bcc48910..ac7d47e4 100644 --- a/GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m +++ b/GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m @@ -17,6 +17,7 @@ #import "GoogleSignIn/Sources/GIDSignInInternalOptions.h" #import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDConfiguration.h" +#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDVerifiableAccountDetail.h" #ifdef SWIFT_PACKAGE @import OCMock; @@ -24,11 +25,42 @@ #import #endif +static NSString * const kClientId = @"FakeClientID"; +static NSString * const kOpenIDRealm = @"FakeRealm"; + @interface GIDSignInInternalOptionsTest : XCTestCase @end @implementation GIDSignInInternalOptionsTest +#if TARGET_OS_IOS +- (void)testDefaultOptionsForVerificationFlow { + GIDConfiguration *configuration = [[GIDConfiguration alloc] initWithClientID:kClientId + serverClientID:nil + hostedDomain:nil + openIDRealm:kOpenIDRealm]; + UIViewController *presentingViewController = [[UIViewController alloc] init]; + GIDVerifiableAccountDetail *ageOver18Detail = [[GIDVerifiableAccountDetail alloc] initWithAccountDetailType:GIDAccountDetailTypeAgeOver18]; + NSArray *accountDetailsToVerify = @[ageOver18Detail]; + NSString *loginHint = @"login_hint"; + + GIDSignInInternalOptions *options = + [GIDSignInInternalOptions defaultOptionsWithConfiguration:configuration + presentingViewController:presentingViewController + loginHint:loginHint + addScopesFlow:YES + accountDetailsToVerify:accountDetailsToVerify + verifyCompletion:nil]; + + XCTAssertTrue(options.interactive); + XCTAssertFalse(options.continuation); + XCTAssertTrue(options.addScopesFlow); + XCTAssertEqual(options.configuration, configuration); + XCTAssertEqual(options.presentingViewController, presentingViewController); + XCTAssertEqual(options.accountDetailsToVerify, accountDetailsToVerify); +} +#endif // TARGET_OS_IOS + - (void)testDefaultOptions { id configuration = OCMStrictClassMock([GIDConfiguration class]); #if TARGET_OS_IOS || TARGET_OS_MACCATALYST