Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/google_sign_in/google_sign_in_ios/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 6.3.1

* Fixes a bug that would cause `authorizeServer` to throw a `PlatformException`
due to an expired or revoked token.

## 6.3.0

* Adds UIScene compatibility.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,15 @@ class GoogleSignInIOS extends GoogleSignInPlatform {
// if the authentication isn't associated with an existing sign-in user
// run the authentication flow first.
if (userId == null) {
SignInResult result = await _api.restorePreviousSignIn();
SignInResult result;
try {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intended design of this plugin is that we catch errors on the native side, where we still have full context. What exactly is throwing here? Is this throwing instead of calling the completion handler?

If so, we should catch it there, inspect the error, and turn this specific one into a known error value, and anything else into an unknown error, via the error return system used by all the other native code in this plugin. (We should also file an issue upstream if that's the case, since that would be surprising behavior.)

Copy link
Copy Markdown
Contributor Author

@felangel felangel Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intended design of this plugin is that we catch errors on the native side, where we still have full context. What exactly is throwing here? Is this throwing instead of calling the completion handler?

I believe that is correct 👍

If so, we should catch it there, inspect the error, and turn this specific one into a known error value, and anything else into an unknown error, via the error return system used by all the other native code in this plugin.

Okay I can try to spend some time on that later this week. Feel free to take this over if you get to it before me.

We should also file an issue upstream if that's the case, since that would be surprising behavior.

Where exactly should this issue be filed?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where exactly should this issue be filed?

If the Google Sign In SDK is throwing an exception instead of calling the callback, that should be filed here.

result = await _api.restorePreviousSignIn();
} on Exception {
Comment thread
felangel marked this conversation as resolved.
// This can throw if the token has expired or been revoked.
// e.g. PlatformException(org.openid.appauth.oauth_token: -10, invalid_grant: Token has been expired or revoked.)
result = SignInResult(error: SignInFailure(type: .unknown));
}

final SignInSuccess? success = result.success;
if (success == null) {
// There's no existing sign-in to use, so return the results of the
Expand Down
2 changes: 1 addition & 1 deletion packages/google_sign_in/google_sign_in_ios/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: google_sign_in_ios
description: iOS implementation of the google_sign_in plugin.
repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in_ios
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22
version: 6.3.0
version: 6.3.1

environment:
sdk: ^3.10.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:google_sign_in_ios/google_sign_in_ios.dart';
import 'package:google_sign_in_ios/src/messages.g.dart';
Expand Down Expand Up @@ -915,6 +916,52 @@ void main() {
},
);

test(
'attempts to authenticate if tokens have expired or been revoked',
() async {
const scopes = <String>['a', 'b'];
when(mockApi.restorePreviousSignIn()).thenThrow(
PlatformException(
code: 'org.openid.appauth.oauth_token: -10',
message: 'invalid_grant: Token has been expired or revoked.',
),
);
when(mockApi.signIn(scopes, null)).thenAnswer(
(_) async => SignInResult(
success: SignInSuccess(
user: UserData(
displayName: _testUser.displayName,
email: _testUser.email,
userId: _testUser.id,
photoUrl: _testUser.photoUrl,
idToken: '',
),
accessToken: '',
grantedScopes: <String>[],
),
),
);

await googleSignIn.serverAuthorizationTokensForScopes(
const ServerAuthorizationTokensForScopesParameters(
request: AuthorizationRequestDetails(
scopes: scopes,
userId: null,
email: null,
promptIfUnauthorized: true,
),
),
);

// With no user ID provided to serverAuthorizationTokensForScopes, the
// implementation should attempt to restore an existing sign-in, and then
// when that throws due to an expired/revoked token, prompt for a combined authn+authz.
// https://github.com/flutter/flutter/issues/184134
verify(mockApi.restorePreviousSignIn());
verify(mockApi.signIn(scopes, null));
},
);

test('attempts to authenticate if no user is provided or already signed in '
'and interaction is allowed', () async {
const scopes = <String>['a', 'b'];
Expand Down
Loading