From 699a005c906157e096992387b7c1235705cb3020 Mon Sep 17 00:00:00 2001 From: Vojtech Novak Date: Sun, 28 Apr 2024 15:35:20 +0200 Subject: [PATCH 1/6] feat: allow providing custom nonce --- GoogleSignIn/Sources/GIDSignIn.m | 27 ++++++++++ .../Sources/GIDSignInInternalOptions.h | 5 ++ .../Sources/GIDSignInInternalOptions.m | 4 ++ .../Sources/Public/GoogleSignIn/GIDSignIn.h | 49 +++++++++++++++++- GoogleSignIn/Tests/Unit/GIDSignInTest.m | 50 ++++++++++++++++--- .../Unit/OIDAuthorizationRequest+Testing.h | 2 + .../Unit/OIDAuthorizationRequest+Testing.m | 5 ++ .../Unit/OIDAuthorizationResponse+Testing.h | 1 + .../Unit/OIDAuthorizationResponse+Testing.m | 5 +- 9 files changed, 138 insertions(+), 10 deletions(-) diff --git a/GoogleSignIn/Sources/GIDSignIn.m b/GoogleSignIn/Sources/GIDSignIn.m index 4b942ed9..32ce7c97 100644 --- a/GoogleSignIn/Sources/GIDSignIn.m +++ b/GoogleSignIn/Sources/GIDSignIn.m @@ -253,12 +253,25 @@ - (void)signInWithPresentingViewController:(UIViewController *)presentingViewCon hint:(nullable NSString *)hint additionalScopes:(nullable NSArray *)additionalScopes completion:(nullable GIDSignInCompletion)completion { + [self signInWithPresentingViewController:presentingViewController + hint:hint + additionalScopes:additionalScopes + nonce:nil + completion:completion]; +} + +- (void)signInWithPresentingViewController:(UIViewController *)presentingViewController + hint:(nullable NSString *)hint + additionalScopes:(nullable NSArray *)additionalScopes + nonce:(nullable NSString *)nonce + completion:(nullable GIDSignInCompletion)completion { GIDSignInInternalOptions *options = [GIDSignInInternalOptions defaultOptionsWithConfiguration:_configuration presentingViewController:presentingViewController loginHint:hint addScopesFlow:NO scopes:additionalScopes + nonce:nonce completion:completion]; [self signInWithOptions:options]; } @@ -331,12 +344,25 @@ - (void)signInWithPresentingWindow:(NSWindow *)presentingWindow hint:(nullable NSString *)hint additionalScopes:(nullable NSArray *)additionalScopes completion:(nullable GIDSignInCompletion)completion { + [self signInWithPresentingWindow:presentingWindow + hint:hint + additionalScopes:additionalScopes + nonce:nil + completion:completion]; +} + +- (void)signInWithPresentingWindow:(NSWindow *)presentingWindow + hint:(nullable NSString *)hint + additionalScopes:(nullable NSArray *)additionalScopes + nonce:(nullable NSString *)nonce + completion:(nullable GIDSignInCompletion)completion { GIDSignInInternalOptions *options = [GIDSignInInternalOptions defaultOptionsWithConfiguration:_configuration presentingWindow:presentingWindow loginHint:hint addScopesFlow:NO scopes:additionalScopes + nonce:nonce completion:completion]; [self signInWithOptions:options]; } @@ -598,6 +624,7 @@ - (void)authenticateInteractivelyWithOptions:(GIDSignInInternalOptions *)options scopes:options.scopes redirectURL:redirectURL responseType:OIDResponseTypeCode + nonce:options.nonce additionalParameters:additionalParameters]; _currentAuthorizationFlow = [OIDAuthorizationService diff --git a/GoogleSignIn/Sources/GIDSignInInternalOptions.h b/GoogleSignIn/Sources/GIDSignInInternalOptions.h index f1aff409..cb77a876 100644 --- a/GoogleSignIn/Sources/GIDSignInInternalOptions.h +++ b/GoogleSignIn/Sources/GIDSignInInternalOptions.h @@ -64,6 +64,9 @@ NS_ASSUME_NONNULL_BEGIN /// The login hint to be used during the flow. @property(nonatomic, copy, nullable) NSString *loginHint; +/// A cryptographically random value used to associate a Client session with an ID Token, and to mitigate replay attacks. +@property(nonatomic, copy, nullable) NSString *nonce; + /// Creates the default options. #if TARGET_OS_IOS || TARGET_OS_MACCATALYST + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)configuration @@ -77,6 +80,7 @@ NS_ASSUME_NONNULL_BEGIN loginHint:(nullable NSString *)loginHint addScopesFlow:(BOOL)addScopesFlow scopes:(nullable NSArray *)scopes + nonce:(nullable NSString *)nonce completion:(nullable GIDSignInCompletion)completion; #elif TARGET_OS_OSX @@ -91,6 +95,7 @@ NS_ASSUME_NONNULL_BEGIN loginHint:(nullable NSString *)loginHint addScopesFlow:(BOOL)addScopesFlow scopes:(nullable NSArray *)scopes + nonce:(nullable NSString *)nonce completion:(nullable GIDSignInCompletion)completion; #endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST diff --git a/GoogleSignIn/Sources/GIDSignInInternalOptions.m b/GoogleSignIn/Sources/GIDSignInInternalOptions.m index bfb21643..523bd48d 100644 --- a/GoogleSignIn/Sources/GIDSignInInternalOptions.m +++ b/GoogleSignIn/Sources/GIDSignInInternalOptions.m @@ -31,6 +31,7 @@ + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)con loginHint:(nullable NSString *)loginHint addScopesFlow:(BOOL)addScopesFlow scopes:(nullable NSArray *)scopes + nonce:(nullable NSString *)nonce completion:(nullable GIDSignInCompletion)completion { #elif TARGET_OS_OSX + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)configuration @@ -38,6 +39,7 @@ + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)con loginHint:(nullable NSString *)loginHint addScopesFlow:(BOOL)addScopesFlow scopes:(nullable NSArray *)scopes + nonce:(nullable NSString *)nonce completion:(nullable GIDSignInCompletion)completion { #endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST GIDSignInInternalOptions *options = [[GIDSignInInternalOptions alloc] init]; @@ -54,6 +56,7 @@ + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)con options->_loginHint = loginHint; options->_completion = completion; options->_scopes = [GIDScopes scopesWithBasicProfile:scopes]; + options->_nonce = nonce; } return options; } @@ -80,6 +83,7 @@ + (instancetype)defaultOptionsWithConfiguration:(nullable GIDConfiguration *)con loginHint:loginHint addScopesFlow:addScopesFlow scopes:@[] + nonce:nil completion:completion]; return options; } diff --git a/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h b/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h index 2576b13d..c9a5ad9d 100644 --- a/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h +++ b/GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h @@ -167,6 +167,31 @@ typedef NS_ERROR_ENUM(kGIDSignInErrorDomain, GIDSignInErrorCode) { NSError *_Nullable error))completion NS_EXTENSION_UNAVAILABLE("The sign-in flow is not supported in App Extensions."); + +/// Starts an interactive sign-in flow on iOS using the provided hint, additional scopes, and nonce. +/// +/// The completion will be called at the end of this process. Any saved sign-in state will be +/// replaced by the result of this flow. Note that this method should not be called when the app is +/// starting up, (e.g in `application:didFinishLaunchingWithOptions:`); instead use the +/// `restorePreviousSignInWithCompletion:` method to restore a previous sign-in. +/// +/// @param presentingViewController The view controller used to present `SFSafariViewController` on +/// iOS 9 and 10. +/// @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 nonce A custom nonce. +/// @param completion The optional block that is called on completion. This block will +/// be called asynchronously on the main queue. +- (void)signInWithPresentingViewController:(UIViewController *)presentingViewController + hint:(nullable NSString *)hint + additionalScopes:(nullable NSArray *)additionalScopes + nonce:(nullable NSString *)nonce + completion: + (nullable void (^)(GIDSignInResult *_Nullable signInResult, + NSError *_Nullable error))completion + NS_EXTENSION_UNAVAILABLE("The sign-in flow is not supported in App Extensions."); + #elif TARGET_OS_OSX /// Starts an interactive sign-in flow on macOS. @@ -200,7 +225,7 @@ typedef NS_ERROR_ENUM(kGIDSignInErrorDomain, GIDSignInErrorCode) { completion:(nullable void (^)(GIDSignInResult *_Nullable signInResult, NSError *_Nullable error))completion; -/// Starts an interactive sign-in flow on macOS using the provided hint. +/// Starts an interactive sign-in flow on macOS using the provided hint and additional scopes. /// /// The completion will be called at the end of this process. Any saved sign-in state will be /// replaced by the result of this flow. Note that this method should not be called when the app is @@ -219,6 +244,28 @@ typedef NS_ERROR_ENUM(kGIDSignInErrorDomain, GIDSignInErrorCode) { completion:(nullable void (^)(GIDSignInResult *_Nullable signInResult, NSError *_Nullable error))completion; +/// Starts an interactive sign-in flow on macOS using the provided hint, additional scopes, and nonce. +/// +/// The completion will be called at the end of this process. Any saved sign-in state will be +/// replaced by the result of this flow. Note that this method should not be called when the app is +/// starting up, (e.g in `application:didFinishLaunchingWithOptions:`); instead use the +/// `restorePreviousSignInWithCompletion:` method to restore a previous sign-in. +/// +/// @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 additionalScopes An optional array of scopes to request in addition to the basic profile scopes. +/// @param nonce A custom nonce. +/// @param completion The optional block that is called on completion. This block will +/// be called asynchronously on the main queue. +- (void)signInWithPresentingWindow:(NSWindow *)presentingWindow + hint:(nullable NSString *)hint + additionalScopes:(nullable NSArray *)additionalScopes + nonce:(nullable NSString *)nonce + completion:(nullable void (^)(GIDSignInResult *_Nullable signInResult, + NSError *_Nullable error))completion; + + #endif @end diff --git a/GoogleSignIn/Tests/Unit/GIDSignInTest.m b/GoogleSignIn/Tests/Unit/GIDSignInTest.m index c64f1611..6a8b937d 100644 --- a/GoogleSignIn/Tests/Unit/GIDSignInTest.m +++ b/GoogleSignIn/Tests/Unit/GIDSignInTest.m @@ -426,8 +426,7 @@ - (void)testRestorePreviousSignInNoRefresh_hasPreviousUser { // Mock generating a GIDConfiguration when initializing GIDGoogleUser. OIDAuthorizationResponse *authResponse = - [OIDAuthorizationResponse testInstanceWithAdditionalParameters:nil - errorString:nil]; + [OIDAuthorizationResponse testInstance]; OCMStub([_authState lastAuthorizationResponse]).andReturn(authResponse); OCMStub([_tokenResponse idToken]).andReturn(kFakeIDToken); @@ -602,7 +601,8 @@ - (void)testOAuthLogin_AdditionalScopes { oldAccessToken:NO modalCancel:NO useAdditionalScopes:YES - additionalScopes:nil]; + additionalScopes:nil + manualNonce:nil]; expectedScopeString = [@[ @"email", @"profile" ] componentsJoinedByString:@" "]; XCTAssertEqualObjects(_savedAuthorizationRequest.scope, expectedScopeString); @@ -616,7 +616,8 @@ - (void)testOAuthLogin_AdditionalScopes { oldAccessToken:NO modalCancel:NO useAdditionalScopes:YES - additionalScopes:@[ kScope ]]; + additionalScopes:@[ kScope ] + manualNonce:nil]; expectedScopeString = [@[ kScope, @"email", @"profile" ] componentsJoinedByString:@" "]; XCTAssertEqualObjects(_savedAuthorizationRequest.scope, expectedScopeString); @@ -630,7 +631,8 @@ - (void)testOAuthLogin_AdditionalScopes { oldAccessToken:NO modalCancel:NO useAdditionalScopes:YES - additionalScopes:@[ kScope, kScope2 ]]; + additionalScopes:@[ kScope, kScope2 ] + manualNonce:nil]; expectedScopeString = [@[ kScope, kScope2, @"email", @"profile" ] componentsJoinedByString:@" "]; XCTAssertEqualObjects(_savedAuthorizationRequest.scope, expectedScopeString); @@ -722,6 +724,35 @@ - (void)testOpenIDRealm { XCTAssertEqual(params[kOpenIDRealmKey], kOpenIDRealm, @"OpenID Realm should match."); } +- (void)testManualNonce { + _signIn.configuration = [[GIDConfiguration alloc] initWithClientID:kClientId + serverClientID:nil + hostedDomain:nil + openIDRealm:kOpenIDRealm]; + + OCMStub( + [_keychainStore saveAuthSession:OCMOCK_ANY error:OCMArg.anyObjectRef] + ).andDo(^(NSInvocation *invocation) { + self->_keychainSaved = self->_saveAuthorizationReturnValue; + }); + + NSString* manualNonce = @"manual_nonce"; + + [self OAuthLoginWithAddScopesFlow:NO + authError:nil + tokenError:nil + emmPasscodeInfoRequired:NO + keychainError:NO + restoredSignIn:NO + oldAccessToken:NO + modalCancel:NO + useAdditionalScopes:NO + additionalScopes:@[] + manualNonce:manualNonce]; + + XCTAssertEqualObjects(_savedAuthorizationRequest.nonce, manualNonce, @"nonce provided to signInWithPresenting[ViewController/Window] should be the same as the one in the authorization request."); +} + - (void)testOAuthLogin_LoginHint { _hint = kUserEmail; @@ -1301,7 +1332,8 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow oldAccessToken:oldAccessToken modalCancel:modalCancel useAdditionalScopes:NO - additionalScopes:nil]; + additionalScopes:nil + manualNonce:nil]; } // The authorization flow with parameters to control which branches to take. @@ -1314,7 +1346,8 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow oldAccessToken:(BOOL)oldAccessToken modalCancel:(BOOL)modalCancel useAdditionalScopes:(BOOL)useAdditionalScopes - additionalScopes:(NSArray *)additionalScopes { + additionalScopes:(NSArray *)additionalScopes + manualNonce:(NSString*)nonce { if (restoredSignIn) { // clearAndAuthenticateWithOptions [[[_authorization expect] andReturn:_authState] authState]; @@ -1326,6 +1359,7 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow @{ @"emm_passcode_info_required" : @"1" } : nil; OIDAuthorizationResponse *authResponse = [OIDAuthorizationResponse testInstanceWithAdditionalParameters:additionalParameters + nonce:nonce errorString:authError]; OIDTokenResponse *tokenResponse = @@ -1401,6 +1435,8 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow [_signIn signInWithPresentingWindow:_presentingWindow #endif // TARGET_OS_IOS || TARGET_OS_MACCATALYST hint:_hint + additionalScopes:nil + nonce:nonce completion:completion]; } } diff --git a/GoogleSignIn/Tests/Unit/OIDAuthorizationRequest+Testing.h b/GoogleSignIn/Tests/Unit/OIDAuthorizationRequest+Testing.h index 310b45b7..bfcca031 100644 --- a/GoogleSignIn/Tests/Unit/OIDAuthorizationRequest+Testing.h +++ b/GoogleSignIn/Tests/Unit/OIDAuthorizationRequest+Testing.h @@ -29,4 +29,6 @@ extern NSString *const OIDAuthorizationRequestTestingCodeVerifier; + (instancetype)testInstance; ++ (instancetype)testInstanceWithNonce:(nullable NSString *)nonce; + @end diff --git a/GoogleSignIn/Tests/Unit/OIDAuthorizationRequest+Testing.m b/GoogleSignIn/Tests/Unit/OIDAuthorizationRequest+Testing.m index 29e9013f..a8dd0b81 100644 --- a/GoogleSignIn/Tests/Unit/OIDAuthorizationRequest+Testing.m +++ b/GoogleSignIn/Tests/Unit/OIDAuthorizationRequest+Testing.m @@ -32,6 +32,10 @@ @implementation OIDAuthorizationRequest (Testing) + (instancetype)testInstance { + return [self testInstanceWithNonce:nil]; +} + ++ (instancetype)testInstanceWithNonce:(nullable NSString *)nonce { return [[OIDAuthorizationRequest alloc] initWithConfiguration:[OIDServiceConfiguration testInstance] clientId:OIDAuthorizationRequestTestingClientID @@ -39,6 +43,7 @@ + (instancetype)testInstance { OIDAuthorizationRequestTestingScope2 ] redirectURL:[NSURL URLWithString:@"http://test.com"] responseType:OIDResponseTypeCode + nonce:nonce additionalParameters:nil]; } diff --git a/GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.h b/GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.h index 4e15ed45..70815a5c 100644 --- a/GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.h +++ b/GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.h @@ -26,6 +26,7 @@ + (instancetype)testInstanceWithAdditionalParameters: (NSDictionary *)additionalParameters + nonce:(NSString*) nonce errorString:(NSString *)errorString; @end diff --git a/GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.m b/GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.m index 78608b66..cc4f1211 100644 --- a/GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.m +++ b/GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.m @@ -25,11 +25,12 @@ @implementation OIDAuthorizationResponse (Testing) + (instancetype)testInstance { - return [self testInstanceWithAdditionalParameters:nil errorString:nil]; + return [self testInstanceWithAdditionalParameters:nil nonce:nil errorString:nil]; } + (instancetype)testInstanceWithAdditionalParameters: (NSDictionary *)additionalParameters + nonce:(NSString *)nonce errorString:(NSString *)errorString { NSMutableDictionary *parameters; @@ -45,7 +46,7 @@ + (instancetype)testInstanceWithAdditionalParameters: [parameters addEntriesFromDictionary:additionalParameters]; } } - return [[OIDAuthorizationResponse alloc] initWithRequest:[OIDAuthorizationRequest testInstance] + return [[OIDAuthorizationResponse alloc] initWithRequest:[OIDAuthorizationRequest testInstanceWithNonce:nonce] parameters:parameters]; } From 3248bd5c646603609a218865841fed8cd541fa5d Mon Sep 17 00:00:00 2001 From: Vojtech Novak Date: Thu, 6 Jun 2024 12:13:05 +0200 Subject: [PATCH 2/6] address review --- GoogleSignIn/Sources/GIDSignIn.m | 1 + GoogleSignIn/Sources/GIDSignInInternalOptions.h | 5 +++-- GoogleSignIn/Tests/Unit/GIDSignInTest.m | 6 ++++-- GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.h | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/GoogleSignIn/Sources/GIDSignIn.m b/GoogleSignIn/Sources/GIDSignIn.m index 9b5afb38..be2ff712 100644 --- a/GoogleSignIn/Sources/GIDSignIn.m +++ b/GoogleSignIn/Sources/GIDSignIn.m @@ -733,6 +733,7 @@ - (void)authorizationRequestWithOptions:(GIDSignInInternalOptions *)options comp scopes:options.scopes redirectURL:[self redirectURLWithOptions:options] responseType:OIDResponseTypeCode + nonce:options.nonce additionalParameters:additionalParameters]; return request; } diff --git a/GoogleSignIn/Sources/GIDSignInInternalOptions.h b/GoogleSignIn/Sources/GIDSignInInternalOptions.h index cb77a876..1ea78f46 100644 --- a/GoogleSignIn/Sources/GIDSignInInternalOptions.h +++ b/GoogleSignIn/Sources/GIDSignInInternalOptions.h @@ -64,8 +64,9 @@ NS_ASSUME_NONNULL_BEGIN /// The login hint to be used during the flow. @property(nonatomic, copy, nullable) NSString *loginHint; -/// A cryptographically random value used to associate a Client session with an ID Token, and to mitigate replay attacks. -@property(nonatomic, copy, nullable) NSString *nonce; +/// A cryptographically random value used to associate a Client session with an ID Token, +/// and to mitigate replay attacks. +@property(nonatomic, readonly, copy, nullable) NSString *nonce; /// Creates the default options. #if TARGET_OS_IOS || TARGET_OS_MACCATALYST diff --git a/GoogleSignIn/Tests/Unit/GIDSignInTest.m b/GoogleSignIn/Tests/Unit/GIDSignInTest.m index baa35a6c..6d6034ce 100644 --- a/GoogleSignIn/Tests/Unit/GIDSignInTest.m +++ b/GoogleSignIn/Tests/Unit/GIDSignInTest.m @@ -824,7 +824,9 @@ - (void)testManualNonce { additionalScopes:@[] manualNonce:manualNonce]; - XCTAssertEqualObjects(_savedAuthorizationRequest.nonce, manualNonce, @"nonce provided to signInWithPresenting[ViewController/Window] should be the same as the one in the authorization request."); + XCTAssertEqualObjects(_savedAuthorizationRequest.nonce, + manualNonce, + @"nonce provided to signInWithPresenting[ViewController/Window] should be the same as the one in the authorization request."); } - (void)testOAuthLogin_LoginHint { @@ -1421,7 +1423,7 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow modalCancel:(BOOL)modalCancel useAdditionalScopes:(BOOL)useAdditionalScopes additionalScopes:(NSArray *)additionalScopes - manualNonce:(NSString*)nonce { + manualNonce:(NSString *)nonce { if (restoredSignIn) { // clearAndAuthenticateWithOptions [[[_authorization expect] andReturn:_authState] authState]; diff --git a/GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.h b/GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.h index 70815a5c..b60c88d1 100644 --- a/GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.h +++ b/GoogleSignIn/Tests/Unit/OIDAuthorizationResponse+Testing.h @@ -26,7 +26,7 @@ + (instancetype)testInstanceWithAdditionalParameters: (NSDictionary *)additionalParameters - nonce:(NSString*) nonce + nonce:(NSString *)nonce errorString:(NSString *)errorString; @end From c414674113062f5b550ef0a728d9338b58888ecd Mon Sep 17 00:00:00 2001 From: Vojtech Novak Date: Mon, 15 Jul 2024 23:14:41 +0200 Subject: [PATCH 3/6] minor refactors --- GoogleSignIn/Sources/GIDSignIn.m | 7 +++---- GoogleSignIn/Tests/Unit/GIDSignInTest.m | 4 ++-- GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.m | 3 +-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/GoogleSignIn/Sources/GIDSignIn.m b/GoogleSignIn/Sources/GIDSignIn.m index be2ff712..de7b6681 100644 --- a/GoogleSignIn/Sources/GIDSignIn.m +++ b/GoogleSignIn/Sources/GIDSignIn.m @@ -599,7 +599,7 @@ - (void)signInWithOptions:(GIDSignInInternalOptions *)options { if (!_configuration) { // NOLINTNEXTLINE(google-objc-avoid-throwing-exception) [NSException raise:NSInvalidArgumentException - format:@"No active configuration. Make sure GIDClientID is set in Info.plist."]; + format:@"No active configuration. Make sure GIDClientID is set in Info.plist."]; return; } @@ -693,7 +693,6 @@ - (void)authorizationRequestWithOptions:(GIDSignInInternalOptions *)options comp [_timedLoader startTiming]; [self->_appCheck getLimitedUseTokenWithCompletion:^(GACAppCheckToken * _Nullable token, NSError * _Nullable error) { - OIDAuthorizationRequest *request = nil; if (token) { additionalParameters[kClientAssertionTypeParameter] = kClientAssertionTypeParameterValue; additionalParameters[kClientAssertionParameter] = token.token; @@ -703,7 +702,7 @@ - (void)authorizationRequestWithOptions:(GIDSignInInternalOptions *)options comp NSLog(@"[Google Sign-In iOS]: Error retrieving App Check limited use token: %@", error); } #endif - request = [self authorizationRequestWithOptions:options + OIDAuthorizationRequest *request = [self authorizationRequestWithOptions:options additionalParameters:additionalParameters]; if (self->_timedLoader.animationStatus == GIDTimedLoaderAnimationStatusAnimating) { [self->_timedLoader stopTimingWithCompletion:^{ @@ -785,7 +784,7 @@ - (NSURL *)redirectURLWithOptions:(GIDSignInInternalOptions *)options { - (void)processAuthorizationResponse:(OIDAuthorizationResponse *)authorizationResponse error:(NSError *)error - emmSupport:(NSString *)emmSupport{ + emmSupport:(NSString *)emmSupport { if (_restarting) { // The auth flow is restarting, so the work here would be performed in the next round. _restarting = NO; diff --git a/GoogleSignIn/Tests/Unit/GIDSignInTest.m b/GoogleSignIn/Tests/Unit/GIDSignInTest.m index 6d6034ce..6bdd19d1 100644 --- a/GoogleSignIn/Tests/Unit/GIDSignInTest.m +++ b/GoogleSignIn/Tests/Unit/GIDSignInTest.m @@ -826,7 +826,7 @@ - (void)testManualNonce { XCTAssertEqualObjects(_savedAuthorizationRequest.nonce, manualNonce, - @"nonce provided to signInWithPresenting[ViewController/Window] should be the same as the one in the authorization request."); + @"Provided nonce should match nonce in authorization request."); } - (void)testOAuthLogin_LoginHint { @@ -1427,7 +1427,7 @@ - (void)OAuthLoginWithAddScopesFlow:(BOOL)addScopesFlow if (restoredSignIn) { // clearAndAuthenticateWithOptions [[[_authorization expect] andReturn:_authState] authState]; - BOOL isAuthorized = restoredSignIn ? YES : NO; + BOOL isAuthorized = restoredSignIn; [[[_authState expect] andReturnValue:[NSNumber numberWithBool:isAuthorized]] isAuthorized]; } diff --git a/GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.m b/GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.m index 49823be7..3285ec8d 100644 --- a/GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.m +++ b/GoogleSignIn/Tests/Unit/OIDTokenResponse+Testing.m @@ -70,8 +70,7 @@ + (instancetype)testInstanceWithIDToken:(NSString *)idToken expiresIn:(NSNumber *)expiresIn refreshToken:(NSString *)refreshToken tokenRequest:(OIDTokenRequest *)tokenRequest { - NSMutableDictionary *parameters; - parameters = [[NSMutableDictionary alloc] initWithDictionary:@{ + NSMutableDictionary *parameters = [[NSMutableDictionary alloc] initWithDictionary:@{ @"access_token" : accessToken ?: kAccessToken, @"expires_in" : expiresIn ?: @(kAccessTokenExpiresIn), @"token_type" : @"example_token_type", From 34d9a65bf94bf5cd7df9d36d8c448f4991bd7f53 Mon Sep 17 00:00:00 2001 From: Vojtech Novak Date: Mon, 15 Jul 2024 23:23:39 +0200 Subject: [PATCH 4/6] update example to use nonce --- Samples/ObjC/SignInSample/Podfile | 2 +- Samples/ObjC/SignInSample/README.md | 2 +- Samples/ObjC/SignInSample/Source/SignInViewController.m | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Samples/ObjC/SignInSample/Podfile b/Samples/ObjC/SignInSample/Podfile index d08d7b41..ba07c279 100644 --- a/Samples/ObjC/SignInSample/Podfile +++ b/Samples/ObjC/SignInSample/Podfile @@ -1,4 +1,4 @@ -platform :ios, '11.0' +platform :ios, '12.0' use_frameworks! target 'SampleForPod' do diff --git a/Samples/ObjC/SignInSample/README.md b/Samples/ObjC/SignInSample/README.md index 82b104a4..50f9392e 100644 --- a/Samples/ObjC/SignInSample/README.md +++ b/Samples/ObjC/SignInSample/README.md @@ -18,7 +18,7 @@ open SignInSampleForPod.xcworkspace 3. Run the 'SampleForPod' target. -## Swift Pacakage Manager +## Swift Package Manager 1. In the `../Sample/ObjC/SignInSample/` folder, open the [Swift Package Manager](https://swift.org/package-manager/) project: diff --git a/Samples/ObjC/SignInSample/Source/SignInViewController.m b/Samples/ObjC/SignInSample/Source/SignInViewController.m index 4898fc8a..da2c25e1 100644 --- a/Samples/ObjC/SignInSample/Source/SignInViewController.m +++ b/Samples/ObjC/SignInSample/Source/SignInViewController.m @@ -247,7 +247,11 @@ - (void)updateButtons { #pragma mark - IBActions - (IBAction)signIn:(id)sender { + NSString* nonce = [[NSUUID UUID] UUIDString]; [GIDSignIn.sharedInstance signInWithPresentingViewController:self + hint:nil + additionalScopes:@[] + nonce:nonce completion:^(GIDSignInResult *signInResult, NSError *error) { if (error) { From d876127d5e2ede61f33406d6d6587801c2ed810d Mon Sep 17 00:00:00 2001 From: Vojtech Novak Date: Wed, 14 Aug 2024 21:43:05 +0200 Subject: [PATCH 5/6] fix compiler warnings --- .../Tests/Unit/OIDAuthorizationRequest+Testing.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/GoogleSignIn/Tests/Unit/OIDAuthorizationRequest+Testing.h b/GoogleSignIn/Tests/Unit/OIDAuthorizationRequest+Testing.h index bfcca031..a70d5e80 100644 --- a/GoogleSignIn/Tests/Unit/OIDAuthorizationRequest+Testing.h +++ b/GoogleSignIn/Tests/Unit/OIDAuthorizationRequest+Testing.h @@ -20,15 +20,15 @@ #import #endif -extern NSString *const OIDAuthorizationRequestTestingClientID; -extern NSString *const OIDAuthorizationRequestTestingScope; -extern NSString *const OIDAuthorizationRequestTestingScope2; -extern NSString *const OIDAuthorizationRequestTestingCodeVerifier; +extern NSString * _Nonnull const OIDAuthorizationRequestTestingClientID; +extern NSString * _Nonnull const OIDAuthorizationRequestTestingScope; +extern NSString * _Nonnull const OIDAuthorizationRequestTestingScope2; +extern NSString * _Nonnull const OIDAuthorizationRequestTestingCodeVerifier; @interface OIDAuthorizationRequest (Testing) -+ (instancetype)testInstance; ++ (instancetype _Nonnull)testInstance; -+ (instancetype)testInstanceWithNonce:(nullable NSString *)nonce; ++ (instancetype _Nonnull)testInstanceWithNonce:(nullable NSString *)nonce; @end From cc077e2429b98df0924a194b4e58aabfb98d55bc Mon Sep 17 00:00:00 2001 From: Vojtech Novak Date: Thu, 15 Aug 2024 20:43:06 +0200 Subject: [PATCH 6/6] use OIDTokenUtilities to generate nonce --- Samples/ObjC/SignInSample/Source/SignInViewController.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Samples/ObjC/SignInSample/Source/SignInViewController.m b/Samples/ObjC/SignInSample/Source/SignInViewController.m index da2c25e1..81ee0ed6 100644 --- a/Samples/ObjC/SignInSample/Source/SignInViewController.m +++ b/Samples/ObjC/SignInSample/Source/SignInViewController.m @@ -21,6 +21,7 @@ #import "AuthInspectorViewController.h" #import "DataPickerState.h" #import "DataPickerViewController.h" +#import static NSString *const kSignInViewTitle = @"Sign-In Sample"; static NSString *const kPlaceholderUserName = @""; @@ -247,10 +248,10 @@ - (void)updateButtons { #pragma mark - IBActions - (IBAction)signIn:(id)sender { - NSString* nonce = [[NSUUID UUID] UUIDString]; + NSString* nonce = [OIDTokenUtilities randomURLSafeStringWithSize:32]; [GIDSignIn.sharedInstance signInWithPresentingViewController:self hint:nil - additionalScopes:@[] + additionalScopes:nil nonce:nonce completion:^(GIDSignInResult *signInResult, NSError *error) {