diff --git a/GoogleSignIn/Sources/GIDSignIn.m b/GoogleSignIn/Sources/GIDSignIn.m index d9cecb6b..c9cc844b 100644 --- a/GoogleSignIn/Sources/GIDSignIn.m +++ b/GoogleSignIn/Sources/GIDSignIn.m @@ -20,6 +20,7 @@ #import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDConfiguration.h" #import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDGoogleUser.h" #import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDProfileData.h" +#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDUserAuth.h" #import "GoogleSignIn/Sources/GIDSignInInternalOptions.h" #import "GoogleSignIn/Sources/GIDSignInPreferences.h" @@ -34,6 +35,7 @@ #import "GoogleSignIn/Sources/GIDAuthentication_Private.h" #import "GoogleSignIn/Sources/GIDGoogleUser_Private.h" #import "GoogleSignIn/Sources/GIDProfileData_Private.h" +#import "GoogleSignIn/Sources/GIDUserAuth_Private.h" #ifdef SWIFT_PACKAGE @import AppAuth; @@ -187,8 +189,16 @@ - (BOOL)hasPreviousSignIn { return [authState isAuthorized]; } -- (void)restorePreviousSignInWithCallback:(nullable GIDSignInCallback)callback { - [self signInWithOptions:[GIDSignInInternalOptions silentOptionsWithCallback:callback]]; +- (void)restorePreviousSignInWithCallback:(nullable void (^)(GIDGoogleUser *_Nullable user, + NSError *_Nullable error))callback { + [self signInWithOptions:[GIDSignInInternalOptions silentOptionsWithCallback: + ^(GIDUserAuth *userAuth, NSError *error) { + if (userAuth) { + callback(userAuth.user, nil); + } else { + callback(nil, error); + } + }]]; } - (BOOL)restorePreviousSignInNoRefresh { @@ -217,7 +227,7 @@ - (BOOL)restorePreviousSignInNoRefresh { - (void)signInWithConfiguration:(GIDConfiguration *)configuration presentingViewController:(UIViewController *)presentingViewController hint:(nullable NSString *)hint - callback:(nullable GIDSignInCallback)callback { + callback:(nullable GIDUserAuthCallback)callback { GIDSignInInternalOptions *options = [GIDSignInInternalOptions defaultOptionsWithConfiguration:configuration presentingViewController:presentingViewController @@ -231,7 +241,7 @@ - (void)signInWithConfiguration:(GIDConfiguration *)configuration presentingViewController:(UIViewController *)presentingViewController hint:(nullable NSString *)hint additionalScopes:(nullable NSArray *)additionalScopes - callback:(nullable GIDSignInCallback)callback { + callback:(nullable GIDUserAuthCallback)callback { GIDSignInInternalOptions *options = [GIDSignInInternalOptions defaultOptionsWithConfiguration:configuration presentingViewController:presentingViewController @@ -244,7 +254,7 @@ - (void)signInWithConfiguration:(GIDConfiguration *)configuration - (void)signInWithConfiguration:(GIDConfiguration *)configuration presentingViewController:(UIViewController *)presentingViewController - callback:(nullable GIDSignInCallback)callback { + callback:(nullable GIDUserAuthCallback)callback { [self signInWithConfiguration:configuration presentingViewController:presentingViewController hint:nil @@ -253,7 +263,7 @@ - (void)signInWithConfiguration:(GIDConfiguration *)configuration - (void)addScopes:(NSArray *)scopes presentingViewController:(UIViewController *)presentingViewController - callback:(nullable GIDSignInCallback)callback { + callback:(nullable GIDUserAuthCallback)callback { // A currentUser must be available in order to complete this flow. if (!self.currentUser) { // No currentUser is set, notify callback of failure. @@ -310,7 +320,7 @@ - (void)addScopes:(NSArray *)scopes - (void)signInWithConfiguration:(GIDConfiguration *)configuration presentingWindow:(NSWindow *)presentingWindow hint:(nullable NSString *)hint - callback:(nullable GIDSignInCallback)callback { + callback:(nullable GIDUserAuthCallback)callback { GIDSignInInternalOptions *options = [GIDSignInInternalOptions defaultOptionsWithConfiguration:configuration presentingWindow:presentingWindow @@ -322,7 +332,7 @@ - (void)signInWithConfiguration:(GIDConfiguration *)configuration - (void)signInWithConfiguration:(GIDConfiguration *)configuration presentingWindow:(NSWindow *)presentingWindow - callback:(nullable GIDSignInCallback)callback { + callback:(nullable GIDUserAuthCallback)callback { [self signInWithConfiguration:configuration presentingWindow:presentingWindow hint:nil @@ -333,7 +343,7 @@ - (void)signInWithConfiguration:(GIDConfiguration *)configuration presentingWindow:(NSWindow *)presentingWindow hint:(nullable NSString *)hint additionalScopes:(nullable NSArray *)additionalScopes - callback:(nullable GIDSignInCallback)callback { + callback:(nullable GIDUserAuthCallback)callback { GIDSignInInternalOptions *options = [GIDSignInInternalOptions defaultOptionsWithConfiguration:configuration presentingWindow:presentingWindow @@ -346,7 +356,7 @@ - (void)signInWithConfiguration:(GIDConfiguration *)configuration - (void)addScopes:(NSArray *)scopes presentingWindow:(NSWindow *)presentingWindow - callback:(nullable GIDSignInCallback)callback { + callback:(nullable GIDUserAuthCallback)callback { // A currentUser must be available in order to complete this flow. if (!self.currentUser) { // No currentUser is set, notify callback of failure. @@ -541,7 +551,8 @@ - (void)signInWithOptions:(GIDSignInInternalOptions *)options { if (options.callback) { self->_currentOptions = nil; dispatch_async(dispatch_get_main_queue(), ^{ - options.callback(self->_currentUser, nil); + GIDUserAuth *userAuth = [[GIDUserAuth alloc] initWithGoogleUser:self->_currentUser serverAuthCode:nil]; + options.callback(userAuth, nil); }); } } @@ -601,7 +612,7 @@ - (void)authenticateInteractivelyWithOptions:(GIDSignInInternalOptions *)options _currentAuthorizationFlow = [OIDAuthorizationService presentAuthorizationRequest:request presentingViewController:options.presentingViewController - callback:^(OIDAuthorizationResponse *_Nullable authorizationResponse, + callback:^(OIDAuthorizationResponse *_Nullable authorizationResponse, NSError *_Nullable error) { [self processAuthorizationResponse:authorizationResponse error:error @@ -882,10 +893,17 @@ - (void)addCompletionCallback:(GIDAuthFlow *)authFlow { [authFlow addCallback:^() { GIDAuthFlow *handlerAuthFlow = weakAuthFlow; if (self->_currentOptions.callback) { - GIDSignInCallback callback = self->_currentOptions.callback; + GIDUserAuthCallback callback = self->_currentOptions.callback; self->_currentOptions = nil; dispatch_async(dispatch_get_main_queue(), ^{ - callback(self->_currentUser, handlerAuthFlow.error); + if (handlerAuthFlow.error) { + callback(nil, handlerAuthFlow.error); + } else { + OIDAuthState *authState = handlerAuthFlow.authState; + NSString *_Nullable serverAuthCode = [authState.lastTokenResponse.additionalParameters[@"server_code"] copy]; + GIDUserAuth *userAuth = [[GIDUserAuth alloc] initWithGoogleUser:self->_currentUser serverAuthCode:serverAuthCode]; + callback(userAuth, nil); + } }); } }]; diff --git a/GoogleSignIn/Sources/GIDSignInInternalOptions.h b/GoogleSignIn/Sources/GIDSignInInternalOptions.h index 72f9b7fa..e8d456ad 100644 --- a/GoogleSignIn/Sources/GIDSignInInternalOptions.h +++ b/GoogleSignIn/Sources/GIDSignInInternalOptions.h @@ -22,9 +22,8 @@ #import #endif -#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h" - @class GIDConfiguration; +@class GIDUserAuth; NS_ASSUME_NONNULL_BEGIN @@ -55,7 +54,8 @@ NS_ASSUME_NONNULL_BEGIN #endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST /// The callback block to be called at the completion of the flow. -@property(nonatomic, readonly, nullable) GIDSignInCallback callback; +@property(nonatomic, readonly, nullable) void (^callback)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error); /// The scopes to be used during the flow. @property(nonatomic, copy, nullable) NSArray *scopes; @@ -69,32 +69,37 @@ NS_ASSUME_NONNULL_BEGIN presentingViewController:(nullable UIViewController *)presentingViewController loginHint:(nullable NSString *)loginHint addScopesFlow:(BOOL)addScopesFlow - callback:(nullable GIDSignInCallback)callback; + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback; + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)configuration presentingViewController:(nullable UIViewController *)presentingViewController loginHint:(nullable NSString *)loginHint addScopesFlow:(BOOL)addScopesFlow scopes:(nullable NSArray *)scopes - callback:(nullable GIDSignInCallback)callback; + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback; #elif TARGET_OS_OSX + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)configuration presentingWindow:(nullable NSWindow *)presentingWindow loginHint:(nullable NSString *)loginHint addScopesFlow:(BOOL)addScopesFlow - callback:(nullable GIDSignInCallback)callback; + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback; + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)configuration presentingWindow:(nullable NSWindow *)presentingWindow loginHint:(nullable NSString *)loginHint addScopesFlow:(BOOL)addScopesFlow scopes:(nullable NSArray *)scopes - callback:(nullable GIDSignInCallback)callback; + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback; #endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST /// Creates the options to sign in silently. -+ (instancetype)silentOptionsWithCallback:(GIDSignInCallback)callback; ++ (instancetype)silentOptionsWithCallback:(void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback; /// Creates options with the same values as the receiver, except for the "extra parameters", and /// continuation flag, which are replaced by the arguments passed to this method. diff --git a/GoogleSignIn/Sources/GIDSignInInternalOptions.m b/GoogleSignIn/Sources/GIDSignInInternalOptions.m index f4ed1488..617c0291 100644 --- a/GoogleSignIn/Sources/GIDSignInInternalOptions.m +++ b/GoogleSignIn/Sources/GIDSignInInternalOptions.m @@ -31,14 +31,16 @@ + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)con loginHint:(nullable NSString *)loginHint addScopesFlow:(BOOL)addScopesFlow scopes:(nullable NSArray *)scopes - callback:(nullable GIDSignInCallback)callback { + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback { #elif TARGET_OS_OSX + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)configuration presentingWindow:(nullable NSWindow *)presentingWindow loginHint:(nullable NSString *)loginHint addScopesFlow:(BOOL)addScopesFlow scopes:(nullable NSArray *)scopes - callback:(nullable GIDSignInCallback)callback { + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback { #endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST GIDSignInInternalOptions *options = [[GIDSignInInternalOptions alloc] init]; @@ -64,13 +66,15 @@ + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)con presentingViewController:(nullable UIViewController *)presentingViewController loginHint:(nullable NSString *)loginHint addScopesFlow:(BOOL)addScopesFlow - callback:(nullable GIDSignInCallback)callback { + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback { #elif TARGET_OS_OSX + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)configuration presentingWindow:(nullable NSWindow *)presentingWindow loginHint:(nullable NSString *)loginHint addScopesFlow:(BOOL)addScopesFlow - callback:(nullable GIDSignInCallback)callback { + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback { #endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST GIDSignInInternalOptions *options = [self defaultOptionsWithConfiguration:configuration #if TARGET_OS_IOS || TARGET_OS_MACCATALYST @@ -85,7 +89,8 @@ + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)con return options; } -+ (instancetype)silentOptionsWithCallback:(GIDSignInCallback)callback { ++ (instancetype)silentOptionsWithCallback:(void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback { GIDSignInInternalOptions *options = [self defaultOptionsWithConfiguration:nil #if TARGET_OS_IOS || TARGET_OS_MACCATALYST presentingViewController:nil @@ -93,7 +98,7 @@ + (instancetype)silentOptionsWithCallback:(GIDSignInCallback)callback { presentingWindow:nil #endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST loginHint:nil - addScopesFlow:NO + addScopesFlow:NO callback:callback]; if (options) { options->_interactive = NO; diff --git a/GoogleSignIn/Sources/GIDSignIn_Private.h b/GoogleSignIn/Sources/GIDSignIn_Private.h index 5d1a6da5..301fcda9 100644 --- a/GoogleSignIn/Sources/GIDSignIn_Private.h +++ b/GoogleSignIn/Sources/GIDSignIn_Private.h @@ -21,6 +21,10 @@ NS_ASSUME_NONNULL_BEGIN @class GIDGoogleUser; @class GIDSignInInternalOptions; +// Represents a callback block that takes a `GIDUserAuth` on success or an error if the operation +// was unsuccessful. +typedef void (^GIDUserAuthCallback)(GIDUserAuth *_Nullable userAuth, NSError *_Nullable error); + // Private |GIDSignIn| methods that are used internally in this SDK and other Google SDKs. @interface GIDSignIn () diff --git a/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h b/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h index 094dffb1..27367565 100644 --- a/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h +++ b/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h @@ -25,6 +25,7 @@ @class GIDConfiguration; @class GIDGoogleUser; +@class GIDUserAuth; NS_ASSUME_NONNULL_BEGIN @@ -50,10 +51,6 @@ typedef NS_ERROR_ENUM(kGIDSignInErrorDomain, GIDSignInErrorCode) { kGIDSignInErrorCodeScopesAlreadyGranted = -8, }; -/// Represents a callback block that takes a `GIDGoogleUser` on success or an error if the operation -/// was unsuccessful. -typedef void (^GIDSignInCallback)(GIDGoogleUser *_Nullable user, NSError *_Nullable error); - /// Represents a callback block that takes an error if the operation was unsuccessful. typedef void (^GIDDisconnectCallback)(NSError *_Nullable error); @@ -91,9 +88,10 @@ typedef void (^GIDDisconnectCallback)(NSError *_Nullable error); /// Attempts to restore a previously authenticated user without interaction. /// -/// @param callback The `GIDSignInCallback` block that is called on completion. This block will be -/// called asynchronously on the main queue. -- (void)restorePreviousSignInWithCallback:(nullable GIDSignInCallback)callback; +/// @param callback The block that is called on completion. This block will be called asynchronously on +/// the main queue. +- (void)restorePreviousSignInWithCallback:(nullable void (^)(GIDGoogleUser *_Nullable user, + NSError *_Nullable error))callback; /// Marks current user as being in the signed out state. - (void)signOut; @@ -117,11 +115,12 @@ typedef void (^GIDDisconnectCallback)(NSError *_Nullable error); /// @param presentingViewController The view controller used to present `SFSafariViewContoller` on /// iOS 9 and 10 and to supply `presentationContextProvider` for `ASWebAuthenticationSession` on /// iOS 13+. -/// @param callback The `GIDSignInCallback` block that is called on completion. This block will be -/// called asynchronously on the main queue. +/// @param callback The block that is called on completion. This block will be called asynchronously on +/// the main queue. - (void)signInWithConfiguration:(GIDConfiguration *)configuration presentingViewController:(UIViewController *)presentingViewController - callback:(nullable GIDSignInCallback)callback + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback NS_EXTENSION_UNAVAILABLE("The sign-in flow is not supported in App Extensions."); /// Starts an interactive sign-in flow on iOS using the provided configuration and a login hint. @@ -137,12 +136,13 @@ typedef void (^GIDDisconnectCallback)(NSError *_Nullable error); /// iOS 13+. /// @param hint An optional hint for the authorization server, for example the user's ID or email /// address, to be prefilled if possible. -/// @param callback The `GIDSignInCallback` block that is called on completion. This block will be -/// called asynchronously on the main queue. +/// @param callback The block that is called on completion. This block will be called asynchronously on +/// the main queue. - (void)signInWithConfiguration:(GIDConfiguration *)configuration presentingViewController:(UIViewController *)presentingViewController hint:(nullable NSString *)hint - callback:(nullable GIDSignInCallback)callback + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback NS_EXTENSION_UNAVAILABLE("The sign-in flow is not supported in App Extensions."); /// Starts an interactive sign-in flow on iOS using the provided configuration and a login hint. @@ -158,14 +158,14 @@ typedef void (^GIDDisconnectCallback)(NSError *_Nullable error); /// @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 callback The `GIDSignInCallback` block that is called on completion. This block will be -/// called asynchronously on the main queue. - +/// @param callback The block that is called on completion. This block will be called asynchronously on +/// the main queue. - (void)signInWithConfiguration:(GIDConfiguration *)configuration presentingViewController:(UIViewController *)presentingViewController hint:(nullable NSString *)hint additionalScopes:(nullable NSArray *)additionalScopes - callback:(nullable GIDSignInCallback)callback; + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback; /// Starts an interactive consent flow on iOS to add scopes to the current user's grants. /// @@ -176,11 +176,12 @@ typedef void (^GIDDisconnectCallback)(NSError *_Nullable error); /// @param presentingViewController The view controller used to present `SFSafariViewContoller` on /// iOS 9 and 10 and to supply `presentationContextProvider` for `ASWebAuthenticationSession` on /// iOS 13+. -/// @param callback The `GIDSignInCallback` block that is called on completion. This block will be -/// called asynchronously on the main queue. +/// @param callback The block that is called on completion. This block will be called asynchronously on +/// the main queue. - (void)addScopes:(NSArray *)scopes presentingViewController:(UIViewController *)presentingViewController - callback:(nullable GIDSignInCallback)callback + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback NS_EXTENSION_UNAVAILABLE("The add scopes flow is not supported in App Extensions."); #elif TARGET_OS_OSX @@ -193,11 +194,12 @@ typedef void (^GIDDisconnectCallback)(NSError *_Nullable error); /// /// @param configuration The configuration properties to be used for this flow. /// @param presentingWindow The window used to supply `presentationContextProvider` for `ASWebAuthenticationSession`. -/// @param callback The `GIDSignInCallback` block that is called on completion. This block will be -/// called asynchronously on the main queue. +/// @param callback The block that is called on completion. This block will be called asynchronously on +/// the main queue. - (void)signInWithConfiguration:(GIDConfiguration *)configuration presentingWindow:(NSWindow *)presentingWindow - callback:(nullable GIDSignInCallback)callback; + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback; /// Starts an interactive sign-in flow on macOS using the provided configuration and a login hint. /// @@ -210,12 +212,13 @@ typedef void (^GIDDisconnectCallback)(NSError *_Nullable error); /// @param presentingWindow The window used to supply `presentationContextProvider` for `ASWebAuthenticationSession`. /// @param hint An optional hint for the authorization server, for example the user's ID or email /// address, to be prefilled if possible. -/// @param callback The `GIDSignInCallback` block that is called on completion. This block will be -/// called asynchronously on the main queue. +/// @param callback The block that is called on completion. This block will be called asynchronously on +/// the main queue. - (void)signInWithConfiguration:(GIDConfiguration *)configuration presentingWindow:(NSWindow *)presentingWindow hint:(nullable NSString *)hint - callback:(nullable GIDSignInCallback)callback; + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback; /// Starts an interactive sign-in flow on macOS using the provided configuration and a login hint. /// @@ -229,14 +232,15 @@ typedef void (^GIDDisconnectCallback)(NSError *_Nullable error); /// @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 callback The `GIDSignInCallback` block that is called on completion. This block will be -/// called asynchronously on the main queue. +/// @param callback The block that is called on completion. This block will be called asynchronously on +/// the main queue. - (void)signInWithConfiguration:(GIDConfiguration *)configuration presentingWindow:(NSWindow *)presentingWindow hint:(nullable NSString *)hint additionalScopes:(nullable NSArray *)additionalScopes - callback:(nullable GIDSignInCallback)callback; + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback; /// Starts an interactive consent flow on macOS to add scopes to the current user's grants. /// @@ -245,11 +249,12 @@ typedef void (^GIDDisconnectCallback)(NSError *_Nullable error); /// /// @param scopes An array of scopes to ask the user to consent to. /// @param presentingWindow The window used to supply `presentationContextProvider` for `ASWebAuthenticationSession`. -/// @param callback The `GIDSignInCallback` block that is called on completion. This block will be -/// called asynchronously on the main queue. +/// @param callback The block that is called on completion. This block will be called asynchronously on +/// the main queue. - (void)addScopes:(NSArray *)scopes presentingWindow:(NSWindow *)presentingWindow - callback:(nullable GIDSignInCallback)callback; + callback:(nullable void (^)(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error))callback; #endif diff --git a/GoogleSignIn/Sources/Public/GoogleSignIn/GoogleSignIn.h b/GoogleSignIn/Sources/Public/GoogleSignIn/GoogleSignIn.h index 091f2c1a..df002612 100644 --- a/GoogleSignIn/Sources/Public/GoogleSignIn/GoogleSignIn.h +++ b/GoogleSignIn/Sources/Public/GoogleSignIn/GoogleSignIn.h @@ -20,6 +20,7 @@ #import "GIDGoogleUser.h" #import "GIDProfileData.h" #import "GIDSignIn.h" +#import "GIDUserAuth.h" #if TARGET_OS_IOS || TARGET_OS_MACCATALYST #import "GIDSignInButton.h" #endif diff --git a/GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m b/GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m index c786bba6..0fddd248 100644 --- a/GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m +++ b/GoogleSignIn/Tests/Unit/GIDSignInInternalOptionsTest.m @@ -37,8 +37,8 @@ - (void)testDefaultOptions { id presentingWindow = OCMStrictClassMock([NSWindow class]); #endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST NSString *loginHint = @"login_hint"; - GIDSignInCallback callback = ^(GIDGoogleUser * _Nullable user, NSError * _Nullable error) {}; - + void (^callback)(GIDUserAuth *_Nullable userAuth, NSError *_Nullable error) = + ^(GIDUserAuth *_Nullable userAuth, NSError * _Nullable error) {}; GIDSignInInternalOptions *options = [GIDSignInInternalOptions defaultOptionsWithConfiguration:configuration #if TARGET_OS_IOS || TARGET_OS_MACCATALYST @@ -47,7 +47,7 @@ - (void)testDefaultOptions { presentingWindow:presentingWindow #endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST loginHint:loginHint - addScopesFlow:NO + addScopesFlow:NO callback:callback]; XCTAssertTrue(options.interactive); XCTAssertFalse(options.continuation); @@ -63,7 +63,8 @@ - (void)testDefaultOptions { } - (void)testSilentOptions { - GIDSignInCallback callback = ^(GIDGoogleUser * _Nullable user, NSError * _Nullable error) {}; + void (^callback)(GIDUserAuth *_Nullable userAuth, NSError *_Nullable error) = + ^(GIDUserAuth *_Nullable userAuth, NSError * _Nullable error) {}; GIDSignInInternalOptions *options = [GIDSignInInternalOptions silentOptionsWithCallback:callback]; XCTAssertFalse(options.interactive); XCTAssertFalse(options.continuation); diff --git a/GoogleSignIn/Tests/Unit/GIDSignInTest.m b/GoogleSignIn/Tests/Unit/GIDSignInTest.m index 070fead1..46e4d36e 100644 --- a/GoogleSignIn/Tests/Unit/GIDSignInTest.m +++ b/GoogleSignIn/Tests/Unit/GIDSignInTest.m @@ -241,7 +241,7 @@ @interface GIDSignInTest : XCTestCase { NSString *_hint; // The callback to be used when testing |GIDSignIn|. - GIDSignInCallback _callback; + void (^_callback)(GIDUserAuth *_Nullable userAuth, NSError *_Nullable error); // The saved authorization request. OIDAuthorizationRequest *_savedAuthorizationRequest; @@ -346,10 +346,10 @@ - (void)setUp { _hint = nil; __weak GIDSignInTest *weakSelf = self; - _callback = ^(GIDGoogleUser * _Nullable user, NSError * _Nullable error) { + _callback = ^(GIDUserAuth *_Nullable userAuth, NSError * _Nullable error) { GIDSignInTest *strongSelf = weakSelf; - if (!user) { - XCTAssertNotNil(error, @"should have an error if user is nil"); + if (!userAuth) { + XCTAssertNotNil(error, @"should have an error if the userAuth is nil"); } XCTAssertFalse(strongSelf->_callbackCalled, @"callback already called"); strongSelf->_callbackCalled = YES; @@ -456,7 +456,7 @@ - (void)testRestorePreviousSignInWhenSignedOut { XCTestExpectation *expectation = [self expectationWithDescription:@"Callback should be called."]; - [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser * _Nullable user, + [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser *_Nullable user, NSError * _Nullable error) { [expectation fulfill]; XCTAssertNotNil(error, @"error should not have been nil"); @@ -1073,6 +1073,7 @@ - (void)testTokenEndpointEMMError { NSError *handledError = [NSError errorWithDomain:kGIDSignInErrorDomain code:kGIDSignInErrorCodeEMM userInfo:emmError.userInfo]; + completion(handledError); [self waitForExpectationsWithTimeout:1 handler:nil]; @@ -1220,10 +1221,13 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow } } else { XCTestExpectation *expectation = [self expectationWithDescription:@"Callback called"]; - GIDSignInCallback callback = ^(GIDGoogleUser * _Nullable user, NSError * _Nullable error) { + void (^callback)(GIDUserAuth *_Nullable userAuth, NSError *_Nullable error) = + ^(GIDUserAuth *_Nullable userAuth, NSError * _Nullable error) { [expectation fulfill]; - if (!user) { - XCTAssertNotNil(error, @"should have an error if user is nil"); + if (userAuth) { + XCTAssertEqualObjects(userAuth.serverAuthCode, kServerAuthCode); + } else { + XCTAssertNotNil(error, @"Should have an error if the userAuth is nil"); } XCTAssertFalse(self->_callbackCalled, @"callback already called"); self->_callbackCalled = YES; @@ -1305,7 +1309,7 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow if (restoredSignIn && oldAccessToken) { XCTestExpectation *expectation = [self expectationWithDescription:@"Callback should be called"]; - [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser * _Nullable user, + [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser *_Nullable user, NSError * _Nullable error) { [expectation fulfill]; XCTAssertNil(error, @"should have no error"); @@ -1348,10 +1352,15 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow profileData:SAVE_TO_ARG_BLOCK(profileData)]; } } + + // CompletionCallback - mock server auth code parsing + if (!keychainError) { + [[[_authState expect] andReturn:tokenResponse] lastTokenResponse]; + } if (restoredSignIn && !oldAccessToken) { XCTestExpectation *expectation = [self expectationWithDescription:@"Callback should be called"]; - [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser * _Nullable user, + [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser *_Nullable user, NSError * _Nullable error) { [expectation fulfill]; XCTAssertNil(error, @"should have no error"); @@ -1361,11 +1370,13 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow _savedTokenCallback(tokenResponse, nil); } - [_authState verify]; if (keychainError) { return; } [self waitForExpectationsWithTimeout:1 handler:nil]; + + [_authState verify]; + XCTAssertTrue(_keychainSaved, @"should save to keychain"); XCTAssertNotNil(authState); // Check fat ID token decoding @@ -1390,7 +1401,7 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow XCTestExpectation *expectation = [self expectationWithDescription:@"Callback should be called"]; - [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser * _Nullable user, + [_signIn restorePreviousSignInWithCallback:^(GIDGoogleUser *_Nullable user, NSError * _Nullable error) { [expectation fulfill]; XCTAssertNil(error, @"should have no error"); diff --git a/Samples/ObjC/SignInSample/Source/SignInViewController.m b/Samples/ObjC/SignInSample/Source/SignInViewController.m index 009e698c..d3fad276 100644 --- a/Samples/ObjC/SignInSample/Source/SignInViewController.m +++ b/Samples/ObjC/SignInSample/Source/SignInViewController.m @@ -259,8 +259,8 @@ - (void)updateButtons { - (IBAction)signIn:(id)sender { [GIDSignIn.sharedInstance signInWithConfiguration:_configuration presentingViewController:self - callback:^(GIDGoogleUser * _Nullable user, - NSError * _Nullable error) { + callback:^(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error) { if (error) { self->_signInAuthStatus.text = [NSString stringWithFormat:@"Status: Authentication error: %@", error]; @@ -278,7 +278,7 @@ - (IBAction)signOut:(id)sender { } - (IBAction)disconnect:(id)sender { - [GIDSignIn.sharedInstance disconnectWithCallback:^(NSError * _Nullable error) { + [GIDSignIn.sharedInstance disconnectWithCallback:^(NSError *_Nullable error) { if (error) { self->_signInAuthStatus.text = [NSString stringWithFormat:@"Status: Failed to disconnect: %@", error]; @@ -293,8 +293,8 @@ - (IBAction)disconnect:(id)sender { - (IBAction)addScopes:(id)sender { [GIDSignIn.sharedInstance addScopes:@[ @"https://www.googleapis.com/auth/user.birthday.read" ] presentingViewController:self - callback:^(GIDGoogleUser * _Nullable user, - NSError * _Nullable error) { + callback:^(GIDUserAuth *_Nullable userAuth, + NSError *_Nullable error) { if (error) { self->_signInAuthStatus.text = [NSString stringWithFormat:@"Status: Failed to add scopes: %@", error]; diff --git a/Samples/Swift/DaysUntilBirthday/Shared/Services/GoogleSignInAuthenticator.swift b/Samples/Swift/DaysUntilBirthday/Shared/Services/GoogleSignInAuthenticator.swift index 2a0e88fd..b798fb10 100644 --- a/Samples/Swift/DaysUntilBirthday/Shared/Services/GoogleSignInAuthenticator.swift +++ b/Samples/Swift/DaysUntilBirthday/Shared/Services/GoogleSignInAuthenticator.swift @@ -48,12 +48,12 @@ final class GoogleSignInAuthenticator: ObservableObject { } GIDSignIn.sharedInstance.signIn(with: configuration, - presenting: rootViewController) { user, error in - guard let user = user else { + presenting: rootViewController) { userAuth, error in + guard let userAuth = userAuth else { print("Error! \(String(describing: error))") return } - self.authViewModel.state = .signedIn(user) + self.authViewModel.state = .signedIn(userAuth.user) } #elseif os(macOS) @@ -63,12 +63,12 @@ final class GoogleSignInAuthenticator: ObservableObject { } GIDSignIn.sharedInstance.signIn(with: configuration, - presenting: presentingWindow) { user, error in - guard let user = user else { + presenting: presentingWindow) { userAuth, error in + guard let userAuth = userAuth else { print("Error! \(String(describing: error))") return } - self.authViewModel.state = .signedIn(user) + self.authViewModel.state = .signedIn(userAuth.user) } #endif } @@ -102,14 +102,14 @@ final class GoogleSignInAuthenticator: ObservableObject { } GIDSignIn.sharedInstance.addScopes([BirthdayLoader.birthdayReadScope], - presenting: rootViewController) { user, error in + presenting: rootViewController) { userAuth, error in if let error = error { print("Found error while adding birthday read scope: \(error).") return } - guard let currentUser = user else { return } - self.authViewModel.state = .signedIn(currentUser) + guard let userAuth = userAuth else { return } + self.authViewModel.state = .signedIn(userAuth.user) completion() } @@ -119,14 +119,14 @@ final class GoogleSignInAuthenticator: ObservableObject { } GIDSignIn.sharedInstance.addScopes([BirthdayLoader.birthdayReadScope], - presenting: presentingWindow) { user, error in + presenting: presentingWindow) { userAuth, error in if let error = error { print("Found error while adding birthday read scope: \(error).") return } - guard let currentUser = user else { return } - self.authViewModel.state = .signedIn(currentUser) + guard let userAuth = userAuth else { return } + self.authViewModel.state = .signedIn(userAuth.user) completion() }