From 92ac13351ebc6681e27e987533ec571c223438dc Mon Sep 17 00:00:00 2001 From: Matt Mathias Date: Wed, 10 Dec 2025 16:36:02 -0800 Subject: [PATCH 1/3] Remove keychain entries if fresh install --- GoogleSignIn/Sources/GIDSignIn.m | 8 ++++++-- GoogleSignIn/Sources/GIDSignIn_Private.h | 3 +++ GoogleSignIn/Tests/Unit/GIDSignInTest.m | 14 ++++++++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/GoogleSignIn/Sources/GIDSignIn.m b/GoogleSignIn/Sources/GIDSignIn.m index 1c043735..015c68c5 100644 --- a/GoogleSignIn/Sources/GIDSignIn.m +++ b/GoogleSignIn/Sources/GIDSignIn.m @@ -119,8 +119,7 @@ // Error string for user cancelations. static NSString *const kUserCanceledError = @"The user canceled the sign-in flow."; -// User preference key to detect fresh install of the app. -static NSString *const kAppHasRunBeforeKey = @"GID_AppHasRunBefore"; +NSString *const kAppHasRunBeforeKey = @"GID_AppHasRunBefore"; // Maximum retry interval in seconds for the fetcher. static const NSTimeInterval kFetcherMaxRetryInterval = 15.0; @@ -553,6 +552,11 @@ - (instancetype)initWithKeychainStore:(GTMKeychainStore *)keychainStore // Check to see if the 3P app is being run for the first time after a fresh install. BOOL isFreshInstall = [self isFreshInstall]; + + // If this is a fresh install, ensure that any pre-existing keychain data is purged. + if (isFreshInstall) { + [self removeAllKeychainEntries]; + } NSString *authorizationEnpointURL = [NSString stringWithFormat:kAuthorizationURLTemplate, [GIDSignInPreferences googleAuthorizationServer]]; diff --git a/GoogleSignIn/Sources/GIDSignIn_Private.h b/GoogleSignIn/Sources/GIDSignIn_Private.h index bb642cb7..803cc10e 100644 --- a/GoogleSignIn/Sources/GIDSignIn_Private.h +++ b/GoogleSignIn/Sources/GIDSignIn_Private.h @@ -32,6 +32,9 @@ NS_ASSUME_NONNULL_BEGIN @class GIDAppCheck; @class GIDAuthStateMigration; +/// User preference key to detect fresh install of the app. +extern NSString *const kAppHasRunBeforeKey; + /// Represents a completion block that takes a `GIDSignInResult` on success or an error if the /// operation was unsuccessful. typedef void (^GIDSignInCompletion)(GIDSignInResult *_Nullable signInResult, diff --git a/GoogleSignIn/Tests/Unit/GIDSignInTest.m b/GoogleSignIn/Tests/Unit/GIDSignInTest.m index b36e197a..0ebfdb34 100644 --- a/GoogleSignIn/Tests/Unit/GIDSignInTest.m +++ b/GoogleSignIn/Tests/Unit/GIDSignInTest.m @@ -119,8 +119,6 @@ @"com.google.UnitTests:///emmcallback?action=unrecognized"; static NSString * const kDevicePolicyAppBundleID = @"com.google.DevicePolicy"; -static NSString * const kAppHasRunBeforeKey = @"GPP_AppHasRunBefore"; - static NSString * const kFingerprintKeychainName = @"fingerprint"; static NSString * const kVerifierKeychainName = @"verifier"; static NSString * const kVerifierKey = @"verifier"; @@ -993,6 +991,18 @@ - (void)testNotHandleWrongPath { XCTAssertFalse(_completionCalled, @"should not call delegate"); } +#pragma mark - Test Fresh Install + +- (void)testFreshInstall_removesKeychainEntries { + // Simulate that the app has been deleted and user defaults removed. + [NSUserDefaults.standardUserDefaults removeObjectForKey:kAppHasRunBeforeKey]; + // Initialization should check `isFreshInstall`. + GIDSignIn *signIn = [[GIDSignIn alloc] initWithKeychainStore:_keychainStore + authStateMigrationService:_authStateMigrationService]; + // If `isFreshInstall`, keychain entries should be removed. + XCTAssertTrue(self->_keychainRemoved); +} + #pragma mark - Tests - disconnectWithCallback: // Verifies disconnect calls callback with no errors if access token is present. From 96c83b660d5781619ae3bf4d906f71e2f3261195 Mon Sep 17 00:00:00 2001 From: Matt Mathias Date: Wed, 10 Dec 2025 16:56:02 -0800 Subject: [PATCH 2/3] Bump pod lib lint OS to macos-15 macos-13 is no longer supported per https://github.com/actions/runner-images/issues/13046 --- .github/workflows/unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index ee5fd660..3db1f824 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - os: [macos-13] + os: [macos-15] podspec: [GoogleSignIn.podspec, GoogleSignInSwiftSupport.podspec] flag: [ "", From d1a3fa68fb292bf1ca717ecfe49c1e9e1f40334b Mon Sep 17 00:00:00 2001 From: Matt Mathias Date: Wed, 10 Dec 2025 17:17:33 -0800 Subject: [PATCH 3/3] Make sure to use signIn within test pod lib lint fails with a warning due to the unused variable --- GoogleSignIn/Tests/Unit/GIDSignInTest.m | 1 + 1 file changed, 1 insertion(+) diff --git a/GoogleSignIn/Tests/Unit/GIDSignInTest.m b/GoogleSignIn/Tests/Unit/GIDSignInTest.m index 0ebfdb34..8db96b41 100644 --- a/GoogleSignIn/Tests/Unit/GIDSignInTest.m +++ b/GoogleSignIn/Tests/Unit/GIDSignInTest.m @@ -1000,6 +1000,7 @@ - (void)testFreshInstall_removesKeychainEntries { GIDSignIn *signIn = [[GIDSignIn alloc] initWithKeychainStore:_keychainStore authStateMigrationService:_authStateMigrationService]; // If `isFreshInstall`, keychain entries should be removed. + XCTAssertNotNil(signIn); XCTAssertTrue(self->_keychainRemoved); }