TF-2384 Handle refresh token from flutter side when NSE refreshed token
Signed-off-by: dab246 <tdvu@linagora.com> (cherry picked from commit 1fddbec1e8030f4e25bc8b0ec5d0d05004215e56)
This commit is contained in:
@@ -52,7 +52,6 @@
|
||||
F5E7D8842B3877050009BB8A /* AuthenticationSSO.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5E7D8832B3877050009BB8A /* AuthenticationSSO.swift */; };
|
||||
F5E7D8862B3877390009BB8A /* TokenResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5E7D8852B3877390009BB8A /* TokenResponse.swift */; };
|
||||
F5E7D8882B38775C0009BB8A /* TokenRefreshManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5E7D8872B38775C0009BB8A /* TokenRefreshManager.swift */; };
|
||||
F5E7D88A2B3877D30009BB8A /* NSEPusher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5E7D8892B3877D30009BB8A /* NSEPusher.swift */; };
|
||||
F5E7D88D2B3878580009BB8A /* AuthenticationInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5E7D88C2B3878580009BB8A /* AuthenticationInterceptor.swift */; };
|
||||
F5EFC07D2B328B9F00829056 /* TwakeLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5EFC07C2B328B9F00829056 /* TwakeLogger.swift */; };
|
||||
F5EFC07E2B328B9F00829056 /* TwakeLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5EFC07C2B328B9F00829056 /* TwakeLogger.swift */; };
|
||||
@@ -155,7 +154,6 @@
|
||||
F5E7D8832B3877050009BB8A /* AuthenticationSSO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationSSO.swift; sourceTree = "<group>"; };
|
||||
F5E7D8852B3877390009BB8A /* TokenResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenResponse.swift; sourceTree = "<group>"; };
|
||||
F5E7D8872B38775C0009BB8A /* TokenRefreshManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenRefreshManager.swift; sourceTree = "<group>"; };
|
||||
F5E7D8892B3877D30009BB8A /* NSEPusher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSEPusher.swift; sourceTree = "<group>"; };
|
||||
F5E7D88C2B3878580009BB8A /* AuthenticationInterceptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationInterceptor.swift; sourceTree = "<group>"; };
|
||||
F5EFC07C2B328B9F00829056 /* TwakeLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwakeLogger.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -349,7 +347,6 @@
|
||||
F5630C7D2B2CE359003CC0FD /* InfoPlistReader.swift */,
|
||||
F5BBBF542B2EEF3D007930E1 /* BundleExtension.swift */,
|
||||
F5630C862B2D0387003CC0FD /* PayloadParser.swift */,
|
||||
F5E7D8892B3877D30009BB8A /* NSEPusher.swift */,
|
||||
);
|
||||
path = Utils;
|
||||
sourceTree = "<group>";
|
||||
@@ -687,7 +684,6 @@
|
||||
F53D1E862B2E401B00051FD0 /* JmapRequestGenerator.swift in Sources */,
|
||||
F5E7D87A2B38763B0009BB8A /* DateExtensions.swift in Sources */,
|
||||
F5E7D88D2B3878580009BB8A /* AuthenticationInterceptor.swift in Sources */,
|
||||
F5E7D88A2B3877D30009BB8A /* NSEPusher.swift in Sources */,
|
||||
F5630C7E2B2CE359003CC0FD /* InfoPlistReader.swift in Sources */,
|
||||
F53D1E662B2DE8B800051FD0 /* AlamofireService.swift in Sources */,
|
||||
F5BBBF532B2EECAA007930E1 /* JmapExceptions.swift in Sources */,
|
||||
|
||||
@@ -2,7 +2,7 @@ import UserNotifications
|
||||
|
||||
class NotificationService: UNNotificationServiceExtension {
|
||||
|
||||
private let timeIntervalNotificationTrigger: Int = 2
|
||||
private let timeIntervalNotificationTriggerInSecond: Int = 2
|
||||
private let newEmailDefaultMessage: String = "You have new emails"
|
||||
|
||||
private var handler: ((UNNotificationContent) -> Void)?
|
||||
@@ -74,7 +74,7 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
self.scheduleLocalNotification(email: email)
|
||||
}
|
||||
|
||||
let delayTimeIntervalNotification: TimeInterval = TimeInterval(self.timeIntervalNotificationTrigger * (emails.count - 1))
|
||||
let delayTimeIntervalNotification: TimeInterval = TimeInterval(self.timeIntervalNotificationTriggerInSecond * (emails.count - 1))
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + delayTimeIntervalNotification) {
|
||||
self.modifiedContent?.subtitle = emails.last?.subject ?? ""
|
||||
@@ -110,7 +110,7 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
content.userInfo[JmapConstants.EMAIL_ID] = "\(email.id)"
|
||||
|
||||
// Create a notification trigger
|
||||
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: TimeInterval(timeIntervalNotificationTrigger), repeats: false)
|
||||
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: TimeInterval(timeIntervalNotificationTriggerInSecond), repeats: false)
|
||||
|
||||
// Create a notification request
|
||||
let request = UNNotificationRequest(identifier: "\(email.id)", content: content, trigger: trigger)
|
||||
|
||||
@@ -92,22 +92,17 @@ class AuthorizationInterceptors extends QueuedInterceptorsWrapper {
|
||||
|
||||
if (_validateToRefreshToken(err)) {
|
||||
log('AuthorizationInterceptors::onError:>> _validateToRefreshToken');
|
||||
final newToken = await _authenticationClient.refreshingTokensOIDC(
|
||||
_configOIDC!.clientId,
|
||||
_configOIDC!.redirectUrl,
|
||||
_configOIDC!.discoveryUrl,
|
||||
_configOIDC!.scopes,
|
||||
_token!.refreshToken
|
||||
);
|
||||
|
||||
_updateNewToken(newToken);
|
||||
|
||||
await _updateCurrentAccount(tokenOIDC: newToken);
|
||||
if (PlatformInfo.isIOS) {
|
||||
_handleRefreshTokenOnIOSPlatform();
|
||||
} else {
|
||||
_handleRefreshTokenOnOtherPlatform();
|
||||
}
|
||||
|
||||
if (extraInRequest.containsKey(FileUploader.uploadAttachmentExtraKey)) {
|
||||
final uploadExtra = extraInRequest[FileUploader.uploadAttachmentExtraKey];
|
||||
|
||||
requestOptions.headers[HttpHeaders.authorizationHeader] = _getTokenAsBearerHeader(newToken.token);
|
||||
requestOptions.headers[HttpHeaders.authorizationHeader] = _getTokenAsBearerHeader(_token!.token);
|
||||
requestOptions.headers[HttpHeaders.contentTypeHeader] = uploadExtra[FileUploader.typeExtraKey];
|
||||
requestOptions.headers[HttpHeaders.contentLengthHeader] = uploadExtra[FileUploader.sizeExtraKey];
|
||||
|
||||
@@ -125,7 +120,7 @@ class AuthorizationInterceptors extends QueuedInterceptorsWrapper {
|
||||
|
||||
return handler.resolve(response);
|
||||
} else {
|
||||
requestOptions.headers[HttpHeaders.authorizationHeader] = _getTokenAsBearerHeader(newToken.token);
|
||||
requestOptions.headers[HttpHeaders.authorizationHeader] = _getTokenAsBearerHeader(_token!.token);
|
||||
|
||||
final response = await _dio.fetch(requestOptions);
|
||||
return handler.resolve(response);
|
||||
@@ -202,7 +197,7 @@ class AuthorizationInterceptors extends QueuedInterceptorsWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
Future _updateCurrentAccount({required TokenOIDC tokenOIDC}) async {
|
||||
Future<PersonalAccount> _updateCurrentAccount({required TokenOIDC tokenOIDC}) async {
|
||||
final currentAccount = await _accountCacheManager.getCurrentAccount();
|
||||
|
||||
await _accountCacheManager.deleteCurrentAccount(currentAccount.id);
|
||||
@@ -219,9 +214,66 @@ class AuthorizationInterceptors extends QueuedInterceptorsWrapper {
|
||||
);
|
||||
await _accountCacheManager.setCurrentAccount(personalAccount);
|
||||
|
||||
if (PlatformInfo.isIOS) {
|
||||
await _iosSharingManager.saveKeyChainSharingSession(personalAccount);
|
||||
return personalAccount;
|
||||
}
|
||||
|
||||
Future<TokenOIDC?> _getTokenInKeychain(TokenOIDC currentTokenOidc) async {
|
||||
final currentAccount = await _accountCacheManager.getCurrentAccount();
|
||||
log('AuthorizationInterceptors::_getTokenInKeychain:currentAccount: $currentAccount');
|
||||
if (currentAccount.accountId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final keychainSharingSession = await _iosSharingManager.getKeychainSharingSession(currentAccount.accountId!);
|
||||
log('AuthorizationInterceptors::_getTokenInKeychain:keychainSharingSession: $keychainSharingSession');
|
||||
if (keychainSharingSession == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (keychainSharingSession.tokenOIDC != null &&
|
||||
currentTokenOidc.token != keychainSharingSession.tokenOIDC!.token) {
|
||||
return keychainSharingSession.tokenOIDC!;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<TokenOIDC> _invokeRefreshTokenFromServer() async {
|
||||
final newToken = await _authenticationClient.refreshingTokensOIDC(
|
||||
_configOIDC!.clientId,
|
||||
_configOIDC!.redirectUrl,
|
||||
_configOIDC!.discoveryUrl,
|
||||
_configOIDC!.scopes,
|
||||
_token!.refreshToken
|
||||
);
|
||||
log('AuthorizationInterceptors::_invokeRefreshTokenFromServer:newToken: $newToken');
|
||||
return newToken;
|
||||
}
|
||||
|
||||
Future _handleRefreshTokenOnIOSPlatform() async {
|
||||
final keychainToken = await _getTokenInKeychain(_token!);
|
||||
|
||||
if (keychainToken == null) {
|
||||
final newToken = await _invokeRefreshTokenFromServer();
|
||||
|
||||
_updateNewToken(newToken);
|
||||
|
||||
final newAccount = await _updateCurrentAccount(tokenOIDC: newToken);
|
||||
|
||||
await _iosSharingManager.saveKeyChainSharingSession(newAccount);
|
||||
} else {
|
||||
_updateNewToken(keychainToken);
|
||||
|
||||
await _updateCurrentAccount(tokenOIDC: keychainToken);
|
||||
}
|
||||
}
|
||||
|
||||
Future _handleRefreshTokenOnOtherPlatform() async {
|
||||
final newToken = await _invokeRefreshTokenFromServer();
|
||||
|
||||
_updateNewToken(newToken);
|
||||
|
||||
await _updateCurrentAccount(tokenOIDC: newToken);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
|
||||
@@ -82,6 +82,19 @@ class IOSSharingManager {
|
||||
}
|
||||
}
|
||||
|
||||
Future<KeychainSharingSession?> getKeychainSharingSession(AccountId accountId) async {
|
||||
try {
|
||||
if (await _keychainSharingManager.isSessionExist(accountId)) {
|
||||
final keychainSharingStored = await _keychainSharingManager.getSharingSession(accountId);
|
||||
return keychainSharingStored;
|
||||
}
|
||||
return null;
|
||||
} catch (e) {
|
||||
logError('IOSSharingManager::getKeychainSharingSession: Exception: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<TokenOIDC?> _getTokenOidc({required String tokeHashId}) async {
|
||||
try {
|
||||
final tokenOidc = await _tokenOidcCacheManager.getTokenOidc(tokeHashId);
|
||||
|
||||
Reference in New Issue
Block a user