diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index 9ae572566f0..d3e6c62eb4c 100644 --- a/packages/google_sign_in/google_sign_in/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md @@ -1,5 +1,7 @@ -## NEXT +## 7.2.0 +* Adds a `clearAuthorizationToken` method to remove an access token from the + cache. * Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. ## 7.1.1 diff --git a/packages/google_sign_in/google_sign_in/MIGRATION.md b/packages/google_sign_in/google_sign_in/MIGRATION.md index 03b627bbe22..524fd1266c1 100644 --- a/packages/google_sign_in/google_sign_in/MIGRATION.md +++ b/packages/google_sign_in/google_sign_in/MIGRATION.md @@ -61,6 +61,7 @@ include: publishing, the only platform that does not support `authenticate` is web, where `google_sign_in_web`'s `renderButton` is used to create a sign-in button. +* `clearAuthCache` has been replaced by `clearAuthorizationToken`. * Outcomes other than successful authentication or authorization will throw `GoogleSignInException`s in most cases, allowing a clear way to distinguish different sign in failure outcomes. This includes the user canceling diff --git a/packages/google_sign_in/google_sign_in/example/pubspec.yaml b/packages/google_sign_in/google_sign_in/example/pubspec.yaml index ee2e2e1d4be..51bf7520b75 100644 --- a/packages/google_sign_in/google_sign_in/example/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/example/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - google_sign_in_web: ^1.0.0 + google_sign_in_web: ^1.1.0 http: ">=0.13.0 <2.0.0" dev_dependencies: diff --git a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart index 9d8caafd0ec..3b00104756b 100644 --- a/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart +++ b/packages/google_sign_in/google_sign_in/lib/google_sign_in.dart @@ -136,6 +136,9 @@ class GoogleSignInAuthorizationClient { /// /// If authorization would require user interaction, this returns null, in /// which case [authorizeScopes] should be used instead. + /// + /// In rare cases, this can return tokens that are no longer valid. See + /// [clearAuthorizationToken] for details. Future authorizationForScopes( List scopes, ) async { @@ -150,6 +153,9 @@ class GoogleSignInAuthorizationClient { /// allowed (for example, while the app is foregrounded on mobile), and if /// [GoogleSignIn.authorizationRequiresUserInteraction] returns true this /// should only be called from an user interaction handler. + /// + /// In rare cases, this can return tokens that are no longer valid. See + /// [clearAuthorizationToken] for details. Future authorizeScopes( List scopes, ) async { @@ -173,8 +179,10 @@ class GoogleSignInAuthorizationClient { /// authorization headers, containing the access token for the given scopes. /// /// Returns null if the given scopes are not authorized, or there is no - /// currently valid authorization token available, and - /// [promptIfNecessary] is false. + /// unexpired authorization token available, and [promptIfNecessary] is false. + /// + /// In rare cases, this can return tokens that are no longer valid. See + /// [clearAuthorizationToken] for details. /// /// See also https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization. Future?> authorizationHeaders( @@ -207,6 +215,9 @@ class GoogleSignInAuthorizationClient { /// allowed (for example, while the app is foregrounded on mobile), and if /// [GoogleSignIn.authorizationRequiresUserInteraction] returns true this /// should only be called from an user interaction handler. + /// + /// In rare cases, this can return tokens that are no longer valid. See + /// [clearAuthorizationToken] for details. Future authorizeServer( List scopes, ) async { @@ -229,6 +240,20 @@ class GoogleSignInAuthorizationClient { ); } + /// Removes the given [accessToken] from any local authorization caches. + /// + /// This should be called if using an access token results in an invalid token + /// response from the target API, followed by re-requsting authorization. + /// + /// A token can be invalidated by, for example, a user removing an + /// application's authorization from outside of the application: + /// https://support.google.com/accounts/answer/13533235. + Future clearAuthorizationToken({required String accessToken}) { + return GoogleSignInPlatform.instance.clearAuthorizationToken( + ClearAuthorizationTokenParams(accessToken: accessToken), + ); + } + Future _authorizeClient( List scopes, { required bool promptIfUnauthorized, diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index 3e2a6f7afa2..56283530e42 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account. repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22 -version: 7.1.1 +version: 7.2.0 environment: sdk: ^3.7.0 @@ -24,10 +24,10 @@ flutter: dependencies: flutter: sdk: flutter - google_sign_in_android: ^7.0.0 - google_sign_in_ios: ^6.0.0 - google_sign_in_platform_interface: ^3.0.0 - google_sign_in_web: ^1.0.0 + google_sign_in_android: ^7.1.0 + google_sign_in_ios: ^6.2.0 + google_sign_in_platform_interface: ^3.1.0 + google_sign_in_web: ^1.1.0 dev_dependencies: build_runner: ^2.1.10 diff --git a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart index b5c29a54c74..84670e53990 100644 --- a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart +++ b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart @@ -760,4 +760,22 @@ void main() { ); }); }); + + group('clearAuthorizationToken', () { + test('passes expected paramaters', () async { + final GoogleSignIn googleSignIn = GoogleSignIn.instance; + + const String token = 'someAccessToken'; + await googleSignIn.authorizationClient.clearAuthorizationToken( + accessToken: token, + ); + + final VerificationResult verification = verify( + mockPlatform.clearAuthorizationToken(captureAny), + ); + final ClearAuthorizationTokenParams params = + verification.captured[0] as ClearAuthorizationTokenParams; + expect(params.accessToken, token); + }); + }); } diff --git a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.mocks.dart b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.mocks.dart index f7db7677e2a..24107898358 100644 --- a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.mocks.dart +++ b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.mocks.dart @@ -1,4 +1,4 @@ -// Mocks generated by Mockito 5.4.5 from annotations +// Mocks generated by Mockito 5.4.6 from annotations // in google_sign_in/test/google_sign_in_test.dart. // Do not manually edit this file. @@ -57,6 +57,14 @@ class MockGoogleSignInPlatform extends _i1.Mock ) as _i4.Future<_i2.AuthenticationResults?>?); + @override + bool supportsAuthenticate() => + (super.noSuchMethod( + Invocation.method(#supportsAuthenticate, []), + returnValue: false, + ) + as bool); + @override _i4.Future<_i2.AuthenticationResults> authenticate( _i2.AuthenticateParameters? params, @@ -72,14 +80,6 @@ class MockGoogleSignInPlatform extends _i1.Mock ) as _i4.Future<_i2.AuthenticationResults>); - @override - bool supportsAuthenticate() => - (super.noSuchMethod( - Invocation.method(#supportsAuthenticate, []), - returnValue: false, - ) - as bool); - @override bool authorizationRequiresUserInteraction() => (super.noSuchMethod( @@ -110,6 +110,17 @@ class MockGoogleSignInPlatform extends _i1.Mock ) as _i4.Future<_i2.ServerAuthorizationTokenData?>); + @override + _i4.Future clearAuthorizationToken( + _i2.ClearAuthorizationTokenParams? params, + ) => + (super.noSuchMethod( + Invocation.method(#clearAuthorizationToken, [params]), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); + @override _i4.Future signOut(_i2.SignOutParams? params) => (super.noSuchMethod(