mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Stop showing the sliding sync proxy alert to any remaining users.
The session will simply fail to restore and the restoration token deleted.
This commit is contained in:
@@ -74,7 +74,6 @@ extension ClientProxyMock {
|
||||
ignoreUserReturnValue = .success(())
|
||||
unignoreUserReturnValue = .success(())
|
||||
|
||||
needsSlidingSyncMigration = false
|
||||
slidingSyncVersion = .native
|
||||
|
||||
trackRecentlyVisitedRoomReturnValue = .success(())
|
||||
|
||||
@@ -2093,11 +2093,6 @@ class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable {
|
||||
set(value) { underlyingHomeserver = value }
|
||||
}
|
||||
var underlyingHomeserver: String!
|
||||
var needsSlidingSyncMigration: Bool {
|
||||
get { return underlyingNeedsSlidingSyncMigration }
|
||||
set(value) { underlyingNeedsSlidingSyncMigration = value }
|
||||
}
|
||||
var underlyingNeedsSlidingSyncMigration: Bool!
|
||||
var slidingSyncVersion: SlidingSyncVersion {
|
||||
get { return underlyingSlidingSyncVersion }
|
||||
set(value) { underlyingSlidingSyncVersion = value }
|
||||
|
||||
@@ -133,10 +133,6 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
setupRoomListSubscriptions()
|
||||
|
||||
updateRooms()
|
||||
|
||||
Task {
|
||||
await checkSlidingSyncMigration()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
@@ -318,24 +314,6 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
state.rooms = rooms
|
||||
}
|
||||
|
||||
/// Check whether we can inform the user about potential migrations
|
||||
/// or have him logout as his proxy is no longer available
|
||||
private func checkSlidingSyncMigration() async {
|
||||
guard userSession.clientProxy.needsSlidingSyncMigration else {
|
||||
return
|
||||
}
|
||||
|
||||
// The proxy is no longer supported so a logout is needed.
|
||||
// Delay setting the alert otherwise it automatically gets dismissed. Same as the crashed last run one
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
self.state.bindings.alertInfo = AlertInfo(id: UUID(),
|
||||
title: L10n.bannerMigrateToNativeSlidingSyncAppForceLogoutTitle(InfoPlistReader.main.bundleDisplayName),
|
||||
primaryButton: .init(title: L10n.bannerMigrateToNativeSlidingSyncAction) { [weak self] in
|
||||
self?.actionsSubject.send(.logoutWithoutConfirmation)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private func markRoomAsFavourite(_ roomID: String, isFavourite: Bool) async {
|
||||
guard case let .joined(roomProxy) = await userSession.clientProxy.roomForIdentifier(roomID) else {
|
||||
MXLog.error("Failed retrieving room for identifier: \(roomID)")
|
||||
|
||||
@@ -150,7 +150,6 @@ class ClientProxy: ClientProxyProtocol {
|
||||
private let sendQueueStatusSubject = CurrentValueSubject<Bool, Never>(false)
|
||||
|
||||
init(client: ClientProtocol,
|
||||
needsSlidingSyncMigration: Bool,
|
||||
networkMonitor: NetworkMonitorProtocol,
|
||||
appSettings: AppSettings) async throws {
|
||||
self.client = client
|
||||
@@ -165,8 +164,6 @@ class ClientProxy: ClientProxyProtocol {
|
||||
|
||||
secureBackupController = SecureBackupController(encryption: client.encryption())
|
||||
|
||||
self.needsSlidingSyncMigration = needsSlidingSyncMigration
|
||||
|
||||
let configuredAppService = try await ClientProxyServices(client: client,
|
||||
actionsSubject: actionsSubject,
|
||||
notificationSettings: notificationSettings,
|
||||
@@ -271,7 +268,6 @@ class ClientProxy: ClientProxyProtocol {
|
||||
client.homeserver()
|
||||
}
|
||||
|
||||
let needsSlidingSyncMigration: Bool
|
||||
var slidingSyncVersion: SlidingSyncVersion {
|
||||
client.slidingSyncVersion()
|
||||
}
|
||||
@@ -341,11 +337,6 @@ class ClientProxy: ClientProxyProtocol {
|
||||
}
|
||||
|
||||
func startSync() {
|
||||
guard !needsSlidingSyncMigration else {
|
||||
MXLog.warning("Ignoring request, this client needs to be migrated to native sliding sync.")
|
||||
return
|
||||
}
|
||||
|
||||
guard !hasEncounteredAuthError else {
|
||||
MXLog.warning("Ignoring request, this client has an unknown token.")
|
||||
return
|
||||
|
||||
@@ -86,9 +86,6 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
||||
|
||||
var homeserver: String { get }
|
||||
|
||||
// TODO: This is a temporary value, in the future we should throw a migration error
|
||||
// when decoding a session that contains a sliding sync proxy URL instead of restoring it.
|
||||
var needsSlidingSyncMigration: Bool { get }
|
||||
var slidingSyncVersion: SlidingSyncVersion { get }
|
||||
|
||||
var canDeactivateAccount: Bool { get }
|
||||
|
||||
@@ -54,8 +54,12 @@ class KeychainController: KeychainControllerProtocol {
|
||||
guard let tokenData = try restorationTokenKeychain.getData(username) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
return try JSONDecoder().decode(RestorationToken.self, from: tokenData)
|
||||
} catch RestorationTokenError.slidingSyncProxyNotSupported {
|
||||
MXLog.error("Unsupported user restore token (contains sliding sync proxy). Deleting token.")
|
||||
removeRestorationTokenForUsername(username)
|
||||
return nil
|
||||
} catch {
|
||||
MXLog.error("Failed retrieving user restore token")
|
||||
return nil
|
||||
@@ -112,8 +116,7 @@ class KeychainController: KeychainControllerProtocol {
|
||||
let restorationToken = RestorationToken(session: session,
|
||||
sessionDirectories: oldToken.sessionDirectories,
|
||||
passphrase: oldToken.passphrase,
|
||||
pusherNotificationClientIdentifier: oldToken.pusherNotificationClientIdentifier,
|
||||
slidingSyncProxyURLString: oldToken.slidingSyncProxyURLString)
|
||||
pusherNotificationClientIdentifier: oldToken.pusherNotificationClientIdentifier)
|
||||
setRestorationToken(restorationToken, forUsername: session.userId)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,19 +8,16 @@
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
enum RestorationTokenError: Error {
|
||||
case slidingSyncProxyNotSupported
|
||||
}
|
||||
|
||||
struct RestorationToken: Equatable {
|
||||
let session: MatrixRustSDK.Session
|
||||
let sessionDirectories: SessionDirectories
|
||||
let passphrase: String?
|
||||
let pusherNotificationClientIdentifier: String?
|
||||
|
||||
/// The sliding sync proxy URL that was previously encoded in the Session.
|
||||
/// This is temporary to help make a nicer user migration flow. In the future
|
||||
/// we will throw when decoding sessions with a sliding sync proxy URL.
|
||||
let slidingSyncProxyURLString: String?
|
||||
/// Whether the token is for a session that is using the now unsupported sliding sync proxy.
|
||||
var needsSlidingSyncMigration: Bool { slidingSyncProxyURLString != nil }
|
||||
|
||||
enum CodingKeys: CodingKey {
|
||||
case session
|
||||
case sessionDirectory
|
||||
@@ -34,7 +31,7 @@ extension RestorationToken: Codable {
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
let sessionWrapper = try container.decode(SessionWrapper.self, forKey: .session)
|
||||
let session = try container.decode(Session.self, forKey: .session)
|
||||
let dataDirectory = try container.decodeIfPresent(URL.self, forKey: .sessionDirectory)
|
||||
let cacheDirectory = try container.decodeIfPresent(URL.self, forKey: .cacheDirectory)
|
||||
|
||||
@@ -45,19 +42,18 @@ extension RestorationToken: Codable {
|
||||
SessionDirectories(dataDirectory: dataDirectory)
|
||||
}
|
||||
} else {
|
||||
SessionDirectories(userID: sessionWrapper.session.userId)
|
||||
SessionDirectories(userID: session.userId)
|
||||
}
|
||||
|
||||
self = try .init(session: sessionWrapper.session,
|
||||
self = try .init(session: session,
|
||||
sessionDirectories: sessionDirectories,
|
||||
passphrase: container.decodeIfPresent(String.self, forKey: .passphrase),
|
||||
pusherNotificationClientIdentifier: container.decodeIfPresent(String.self, forKey: .pusherNotificationClientIdentifier),
|
||||
slidingSyncProxyURLString: sessionWrapper.slidingSyncProxyURLString)
|
||||
pusherNotificationClientIdentifier: container.decodeIfPresent(String.self, forKey: .pusherNotificationClientIdentifier))
|
||||
}
|
||||
|
||||
func encode(to encoder: any Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(SessionWrapper(session: session, slidingSyncProxyURLString: slidingSyncProxyURLString), forKey: .session)
|
||||
try container.encode(session, forKey: .session)
|
||||
try container.encode(sessionDirectories.dataDirectory, forKey: .sessionDirectory)
|
||||
try container.encode(sessionDirectories.cacheDirectory, forKey: .cacheDirectory)
|
||||
try container.encode(passphrase, forKey: .passphrase)
|
||||
@@ -65,33 +61,20 @@ extension RestorationToken: Codable {
|
||||
}
|
||||
}
|
||||
|
||||
/// Temporary struct to smooth the forced migration by keeping a user session.
|
||||
/// In the future we can remove this and throw a migration error when the URL
|
||||
/// is decoded to a non-nil value.
|
||||
private struct SessionWrapper {
|
||||
let session: MatrixRustSDK.Session
|
||||
let slidingSyncProxyURLString: String?
|
||||
}
|
||||
|
||||
extension SessionWrapper: Codable {
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: MatrixRustSDK.Session.CodingKeys.self)
|
||||
session = try Session(from: decoder)
|
||||
|
||||
// TODO: In the future we should decode this in the Session and throw a migration error if it contains a value.
|
||||
slidingSyncProxyURLString = try container.decodeIfPresent(String.self, forKey: .slidingSyncProxy)
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: MatrixRustSDK.Session.CodingKeys.self)
|
||||
try session.encode(to: encoder)
|
||||
try container.encode(slidingSyncProxyURLString, forKey: .slidingSyncProxy)
|
||||
}
|
||||
}
|
||||
|
||||
extension MatrixRustSDK.Session: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
// The SDK no longer supports sliding sync proxies. We must bail here otherwise the
|
||||
// session would be restored using native sliding sync, but if the proxy was still
|
||||
// active its sync loop would be stealing keys away from us.
|
||||
//
|
||||
// Note: As tempting as it is to use container.contains(.slidingSyncProxy), that will always
|
||||
// return true as our coding keys have resulted in the key being encoded with a nil value 🤦♂️.
|
||||
if (try? container.decodeIfPresent(String.self, forKey: .slidingSyncProxy)) != nil {
|
||||
throw RestorationTokenError.slidingSyncProxyNotSupported
|
||||
}
|
||||
|
||||
self = try .init(accessToken: container.decode(String.self, forKey: .accessToken),
|
||||
refreshToken: container.decodeIfPresent(String.self, forKey: .refreshToken),
|
||||
userId: container.decode(String.self, forKey: .userId),
|
||||
|
||||
@@ -64,13 +64,12 @@ class UserSessionStore: UserSessionStoreProtocol {
|
||||
do {
|
||||
let session = try client.session()
|
||||
let userID = try client.userId()
|
||||
let clientProxy = try await setupProxyForClient(client, needsSlidingSyncMigration: false)
|
||||
let clientProxy = try await setupProxyForClient(client)
|
||||
|
||||
keychainController.setRestorationToken(RestorationToken(session: session,
|
||||
sessionDirectories: sessionDirectories,
|
||||
passphrase: passphrase,
|
||||
pusherNotificationClientIdentifier: clientProxy.pusherNotificationClientIdentifier,
|
||||
slidingSyncProxyURLString: nil),
|
||||
pusherNotificationClientIdentifier: clientProxy.pusherNotificationClientIdentifier),
|
||||
forUsername: userID)
|
||||
|
||||
MXLog.info("Set up session for user \(userID) at: \(sessionDirectories)")
|
||||
@@ -141,7 +140,7 @@ class UserSessionStore: UserSessionStoreProtocol {
|
||||
|
||||
Task(priority: .low) { await appHooks.remoteSettingsHook.updateCache(using: client) }
|
||||
|
||||
return try await .success(setupProxyForClient(client, needsSlidingSyncMigration: credentials.restorationToken.needsSlidingSyncMigration))
|
||||
return try await .success(setupProxyForClient(client))
|
||||
} catch UserSessionStoreError.failedSettingUpClientProxy(let error) {
|
||||
// If this has failed, there is likely something wrong with the creation of the sync service
|
||||
// There is nothing we can do, but at the same time we don't want the user to the get logged out
|
||||
@@ -153,10 +152,9 @@ class UserSessionStore: UserSessionStoreProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
private func setupProxyForClient(_ client: ClientProtocol, needsSlidingSyncMigration: Bool) async throws -> ClientProxyProtocol {
|
||||
private func setupProxyForClient(_ client: ClientProtocol) async throws -> ClientProxyProtocol {
|
||||
do {
|
||||
return try await ClientProxy(client: client,
|
||||
needsSlidingSyncMigration: needsSlidingSyncMigration,
|
||||
networkMonitor: networkMonitor,
|
||||
appSettings: appSettings)
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user