3838// Key constants used for encode and decode.
3939static NSString *const kAuthenticationKey = @" authentication" ;
4040static NSString *const kProfileDataKey = @" profileData" ;
41- static NSString *const kAuthState = @" authState" ;
41+ static NSString *const kAuthStateKey = @" authState" ;
4242
4343// Parameters for the token exchange endpoint.
4444static NSString *const kAudienceParameter = @" audience" ;
4848static NSString *const kEMMSupportParameterName = @" emm_support" ;
4949
5050// Minimal time interval before expiration for the access token or it needs to be refreshed.
51- NSTimeInterval kMinimalTimeToExpire = 60.0 ;
51+ static NSTimeInterval const kMinimalTimeToExpire = 60.0 ;
52+
53+ #pragma mark - GIDAuthentication
54+
55+ // Internal class for GIDGoogleUser decoding backward compatibility.
56+ @interface GIDAuthentication : NSObject <NSSecureCoding >
57+
58+ @property (nonatomic ) OIDAuthState* authState;
59+
60+ - (instancetype )initWithAuthState : (OIDAuthState *)authState ;
61+
62+ @end
63+
64+ @implementation GIDAuthentication
65+
66+ - (instancetype )initWithAuthState : (OIDAuthState *)authState {
67+ _authState = authState;
68+ }
69+
70+ #pragma mark - NSSecureCoding
71+
72+ + (BOOL )supportsSecureCoding {
73+ return YES ;
74+ }
75+
76+ - (nullable instancetype )initWithCoder : (NSCoder *)decoder {
77+ self = [super init ];
78+ if (self) {
79+ _authState = [decoder decodeObjectOfClass: [OIDAuthState class ] forKey: kAuthStateKey ];
80+ }
81+ return self;
82+ }
83+
84+ - (void )encodeWithCoder : (NSCoder *)encoder {
85+ [encoder encodeObject: _authState forKey: kAuthStateKey ];
86+ }
87+
88+ @end
89+
90+ #pragma mark - GIDGoogleUser
5291
5392@implementation GIDGoogleUser {
5493 OIDAuthState *_authState;
5594 GIDConfiguration *_cachedConfiguration;
5695
57- // A queue for pending refrsh token handlers so we don't fire multiple requests in parallel.
96+ // A queue for pending token refresh handlers so we don't fire multiple requests in parallel.
5897 // Access to this ivar should be synchronized.
59- NSMutableArray *_refreshTokensHandlerQueue ;
98+ NSMutableArray <GIDGoogleUserCompletion> *_tokenRefreshHandlerQueue ;
6099}
61100
62101- (nullable NSString *)userID {
@@ -116,10 +155,10 @@ - (void)doWithFreshTokens:(GIDGoogleUserCompletion)completion {
116155 });
117156 return ;
118157 }
119- @synchronized (_refreshTokensHandlerQueue ) {
158+ @synchronized (_tokenRefreshHandlerQueue ) {
120159 // Push the handler into the callback queue.
121- [_refreshTokensHandlerQueue addObject: [completion copy ]];
122- if (_refreshTokensHandlerQueue .count > 1 ) {
160+ [_tokenRefreshHandlerQueue addObject: [completion copy ]];
161+ if (_tokenRefreshHandlerQueue .count > 1 ) {
123162 // This is not the first handler in the queue, no fetch is needed.
124163 return ;
125164 }
@@ -153,10 +192,10 @@ - (void)doWithFreshTokens:(GIDGoogleUserCompletion)completion {
153192#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
154193 [GIDEMMSupport handleTokenFetchEMMError: error completion: ^(NSError *_Nullable error) {
155194 // Process the handler queue to call back.
156- NSArray *refreshTokensHandlerQueue;
157- @synchronized (self->_refreshTokensHandlerQueue ) {
158- refreshTokensHandlerQueue = [self ->_refreshTokensHandlerQueue copy ];
159- [self ->_refreshTokensHandlerQueue removeAllObjects ];
195+ NSArray <GIDGoogleUserCompletion> *refreshTokensHandlerQueue;
196+ @synchronized (self->_tokenRefreshHandlerQueue ) {
197+ refreshTokensHandlerQueue = [self ->_tokenRefreshHandlerQueue copy ];
198+ [self ->_tokenRefreshHandlerQueue removeAllObjects ];
160199 }
161200 for (GIDGoogleUserCompletion completion in refreshTokensHandlerQueue) {
162201 dispatch_async (dispatch_get_main_queue (), ^{
@@ -165,10 +204,10 @@ - (void)doWithFreshTokens:(GIDGoogleUserCompletion)completion {
165204 }
166205 }];
167206#elif TARGET_OS_OSX || TARGET_OS_MACCATALYST
168- NSArray *refreshTokensHandlerQueue;
169- @synchronized (self->_refreshTokensHandlerQueue ) {
170- refreshTokensHandlerQueue = [self ->_refreshTokensHandlerQueue copy ];
171- [self ->_refreshTokensHandlerQueue removeAllObjects ];
207+ NSArray <GIDGoogleUserCompletion> *refreshTokensHandlerQueue;
208+ @synchronized (self->_tokenRefreshHandlerQueue ) {
209+ refreshTokensHandlerQueue = [self ->_tokenRefreshHandlerQueue copy ];
210+ [self ->_tokenRefreshHandlerQueue removeAllObjects ];
172211 }
173212 for (GIDGoogleUserCompletion completion in refreshTokensHandlerQueue) {
174213 dispatch_async (dispatch_get_main_queue (), ^{
@@ -192,7 +231,7 @@ - (instancetype)initWithAuthState:(OIDAuthState *)authState
192231 profileData : (nullable GIDProfileData *)profileData {
193232 self = [super init ];
194233 if (self) {
195- _refreshTokensHandlerQueue = [[NSMutableArray alloc ] init ];
234+ _tokenRefreshHandlerQueue = [[NSMutableArray alloc ] init ];
196235 _authState = authState;
197236 _authState.stateChangeDelegate = self;
198237 _profile = profileData;
@@ -292,30 +331,26 @@ + (BOOL)supportsSecureCoding {
292331- (nullable instancetype )initWithCoder : (NSCoder *)decoder {
293332 self = [super init ];
294333 if (self) {
295- _refreshTokensHandlerQueue = [[NSMutableArray alloc ] init ];
296- _profile = [decoder decodeObjectOfClass: [GIDProfileData class ] forKey: kProfileDataKey ];
297- _authState = [decoder decodeObjectOfClass: [OIDAuthState class ] forKey: kAuthState ];
298- _authState.stateChangeDelegate = self;
334+ GIDProfileData *profile =
335+ [decoder decodeObjectOfClass: [GIDProfileData class ] forKey: kProfileDataKey ];
299336
300- #if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
301- GTMAppAuthFetcherAuthorization *authorization = self.emmSupport ?
302- [[GIDAppAuthFetcherAuthorizationWithEMMSupport alloc ] initWithAuthState: _authState] :
303- [[GTMAppAuthFetcherAuthorization alloc ] initWithAuthState: _authState];
304- #elif TARGET_OS_OSX || TARGET_OS_MACCATALYST
305- GTMAppAuthFetcherAuthorization *authorization =
306- [[GTMAppAuthFetcherAuthorization alloc ] initWithAuthState: _authState];
307- #endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST
308- authorization.tokenRefreshDelegate = self;
309- self.fetcherAuthorizer = authorization;
337+ OIDAuthState *authState;
338+ if ([decoder containsValueForKey: kAuthStateKey ]) { // Current encoding
339+ authState = [decoder decodeObjectOfClass: [OIDAuthState class ] forKey: kAuthStateKey ];
340+ } else { // Old encoding
341+ GIDAuthentication *authentication = [decoder decodeObjectOfClass: [GIDAuthentication class ]
342+ forKey: kAuthenticationKey ];
343+ authState = authentication.authState ;
344+ }
310345
311- [self updateTokensWithAuthState: _authState ];
346+ self = [self initWithAuthState: authState profileData: profile ];
312347 }
313348 return self;
314349}
315350
316351- (void )encodeWithCoder : (NSCoder *)encoder {
317352 [encoder encodeObject: _profile forKey: kProfileDataKey ];
318- [encoder encodeObject: _authState forKey: kAuthState ];
353+ [encoder encodeObject: _authState forKey: kAuthStateKey ];
319354}
320355
321356@end
0 commit comments