From f8b613edd956c36aca96c8b948f858f4b9cd2579 Mon Sep 17 00:00:00 2001 From: Philippe Weidmann Date: Fri, 19 Jan 2024 15:02:54 +0100 Subject: [PATCH 1/2] fix: Prevent replacing wrong token --- MailCore/API/SyncedAuthenticator.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MailCore/API/SyncedAuthenticator.swift b/MailCore/API/SyncedAuthenticator.swift index 7301997d5..7f36d077c 100644 --- a/MailCore/API/SyncedAuthenticator.swift +++ b/MailCore/API/SyncedAuthenticator.swift @@ -59,6 +59,17 @@ final class SyncedAuthenticator: OAuthAuthenticator { return } + // Maybe someone else refreshed our token + if let storedToken = tokenStore.tokenFor(userId: credential.userId, fetchLocation: .keychain), + storedToken.expirationDate == nil && storedToken.accessToken != credential.accessToken { + SentrySDK.addBreadcrumb(storedToken.generateBreadcrumb( + level: .info, + message: "Refreshing token - Success with local" + )) + completion(.success(storedToken)) + return + } + // It is absolutely necessary that the app stays awake while we refresh the token BackgroundExecutor.executeWithBackgroundTask { endBackgroundTask in self.networkLoginService.refreshToken(token: credential) { token, error in From 90cfbe925feed2ae43415a9610d00a8987e783dc Mon Sep 17 00:00:00 2001 From: Philippe Weidmann Date: Wed, 24 Jan 2024 16:08:08 +0100 Subject: [PATCH 2/2] fix: Ensure correct token is used on refresh --- MailCore/API/SyncedAuthenticator.swift | 30 ++++++++++++++++++-------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/MailCore/API/SyncedAuthenticator.swift b/MailCore/API/SyncedAuthenticator.swift index 7f36d077c..2aab63a7d 100644 --- a/MailCore/API/SyncedAuthenticator.swift +++ b/MailCore/API/SyncedAuthenticator.swift @@ -59,15 +59,27 @@ final class SyncedAuthenticator: OAuthAuthenticator { return } - // Maybe someone else refreshed our token - if let storedToken = tokenStore.tokenFor(userId: credential.userId, fetchLocation: .keychain), - storedToken.expirationDate == nil && storedToken.accessToken != credential.accessToken { - SentrySDK.addBreadcrumb(storedToken.generateBreadcrumb( - level: .info, - message: "Refreshing token - Success with local" - )) - completion(.success(storedToken)) - return + if let storedToken = tokenStore.tokenFor(userId: credential.userId, fetchLocation: .keychain) { + // Someone else refreshed our token and we already have an infinite token + if storedToken.expirationDate == nil && credential.expirationDate != nil { + SentrySDK.addBreadcrumb(storedToken.generateBreadcrumb( + level: .info, + message: "Refreshing token - Success with local (infinite)" + )) + completion(.success(storedToken)) + return + } + // Someone else refreshed our token and we don't have an infinite token + if let storedTokenExpirationDate = storedToken.expirationDate, + let tokenExpirationDate = credential.expirationDate, + tokenExpirationDate > storedTokenExpirationDate { + SentrySDK.addBreadcrumb(storedToken.generateBreadcrumb( + level: .info, + message: "Refreshing token - Success with local" + )) + completion(.success(storedToken)) + return + } } // It is absolutely necessary that the app stays awake while we refresh the token