@@ -19,6 +19,24 @@ class GoogleSignInIOS extends GoogleSignInPlatform {
1919
2020 String ? _nonce;
2121
22+ /// The last server auth code returned when authenticating or adding scopes.
23+ ///
24+ /// The SDK only returns an auth code when doing a new authentication or
25+ /// when first adding new scopes; later calls to get refreshed tokens will not
26+ /// provide the server auth code again. Because this plugin separates out
27+ /// separate calls for authn, client authz, and server authz, the server auth
28+ /// token needs to be cached when it was returned so that it can be returned
29+ /// later in the session.
30+ ///
31+ /// There is a small risk of returning an expired server auth token this way,
32+ /// but the plugin docs are clear that clients should obtain the server auth
33+ /// token immediately, and not rely on it continuing to be valid later.
34+ String ? _cachedServerAuthCode;
35+
36+ /// The user identifier for the cached server auth code, to ensure that a
37+ /// cached code isn't returned across users.
38+ String ? _cachedServerAuthCodeUserId;
39+
2240 /// Registers this class as the default instance of [GoogleSignInPlatform] .
2341 static void registerWith () {
2442 GoogleSignInPlatform .instance = GoogleSignInIOS ();
@@ -70,7 +88,7 @@ class GoogleSignInIOS extends GoogleSignInPlatform {
7088 Future <AuthenticationResults > authenticate (
7189 AuthenticateParameters params,
7290 ) async {
73- final SignInResult result = await _api. signIn (params.scopeHint, _nonce);
91+ final SignInResult result = await _signIn (params.scopeHint, _nonce);
7492
7593 // This should never happen; the corresponding native error code is
7694 // documented as being specific to restorePreviousSignIn.
@@ -100,6 +118,7 @@ class GoogleSignInIOS extends GoogleSignInPlatform {
100118
101119 @override
102120 Future <void > signOut (SignOutParams params) {
121+ _updateAuthCodeCache (null );
103122 return _api.signOut ();
104123 }
105124
@@ -155,7 +174,7 @@ class GoogleSignInIOS extends GoogleSignInPlatform {
155174 // There's no existing sign-in to use, so return the results of the
156175 // combined authn+authz flow, if prompting is allowed.
157176 if (request.promptIfUnauthorized) {
158- result = await _api. signIn (request.scopes, _nonce);
177+ result = await _signIn (request.scopes, _nonce);
159178 return _processAuthorizationResult (result);
160179 } else {
161180 // No existing authentication, and no prompting allowed, so return
@@ -174,7 +193,7 @@ class GoogleSignInIOS extends GoogleSignInPlatform {
174193 SignInResult result =
175194 useExistingAuthorization
176195 ? await _api.getRefreshedAuthorizationTokens (userId)
177- : await _api. addScopes (request.scopes, userId);
196+ : await _addScopes (request.scopes, userId);
178197 if (! useExistingAuthorization &&
179198 result.error? .type == GoogleSignInErrorCode .scopesAlreadyGranted) {
180199 // The Google Sign In SDK returns an error when requesting scopes that are
@@ -230,6 +249,28 @@ class GoogleSignInIOS extends GoogleSignInPlatform {
230249 return _authorizationTokenDataFromSignInSuccess (result.success);
231250 }
232251
252+ Future <SignInResult > _signIn (List <String > scopeHint, String ? nonce) async {
253+ final SignInResult result = await _api.signIn (scopeHint, nonce);
254+ _updateAuthCodeCache (result.success);
255+ return result;
256+ }
257+
258+ Future <SignInResult > _addScopes (List <String > scopes, String userId) async {
259+ final SignInResult result = await _api.addScopes (scopes, userId);
260+ // Don't clear the cache for GoogleSignInErrorCode.scopesAlreadyGranted
261+ // since that indicates that nothing has changed. Otherwise, update the
262+ // cache (with a new token on success, or clearing on failure).
263+ if (result.error? .type != GoogleSignInErrorCode .scopesAlreadyGranted) {
264+ _updateAuthCodeCache (result.success);
265+ }
266+ return result;
267+ }
268+
269+ void _updateAuthCodeCache (SignInSuccess ? success) {
270+ _cachedServerAuthCode = success? .serverAuthCode;
271+ _cachedServerAuthCodeUserId = success? .user.userId;
272+ }
273+
233274 AuthenticationResults _authenticationResultsFromSignInSuccess (
234275 SignInSuccess result,
235276 ) {
@@ -248,9 +289,15 @@ class GoogleSignInIOS extends GoogleSignInPlatform {
248289
249290 ({String ? accessToken, String ? serverAuthCode})
250291 _authorizationTokenDataFromSignInSuccess (SignInSuccess ? result) {
292+ // Check for a relevant cached auth code to add if needed.
293+ final String ? cachedAuthCode =
294+ result != null && result.user.userId == _cachedServerAuthCodeUserId
295+ ? _cachedServerAuthCode
296+ : null ;
297+
251298 return (
252299 accessToken: result? .accessToken,
253- serverAuthCode: result? .serverAuthCode,
300+ serverAuthCode: result? .serverAuthCode ?? cachedAuthCode ,
254301 );
255302 }
256303
0 commit comments