mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-05 11:58:32 +00:00
Update the SDK.
Handles changes that removed support for the sliding sync proxy.
This commit is contained in:
@@ -27,55 +27,25 @@ struct AuthenticationClientBuilder: AuthenticationClientBuilderProtocol {
|
||||
|
||||
/// Builds a Client for login using OIDC or password authentication.
|
||||
func build(homeserverAddress: String) async throws -> ClientProtocol {
|
||||
if appSettings.slidingSyncDiscovery == .forceNative {
|
||||
return try await makeClientBuilder(slidingSync: .forceNative).serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build()
|
||||
}
|
||||
|
||||
if appSettings.slidingSyncDiscovery == .native {
|
||||
do {
|
||||
return try await makeClientBuilder(slidingSync: .discoverNative).serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build()
|
||||
} catch {
|
||||
MXLog.warning("Native sliding sync not available: \(error)")
|
||||
MXLog.info("Falling back to a sliding sync proxy.")
|
||||
}
|
||||
}
|
||||
|
||||
return try await makeClientBuilder(slidingSync: .discoverProxy).serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build()
|
||||
try await makeClientBuilder().serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build()
|
||||
}
|
||||
|
||||
/// Builds a Client, authenticating with the given QR code data.
|
||||
func buildWithQRCode(qrCodeData: QrCodeData,
|
||||
oidcConfiguration: OIDCConfigurationProxy,
|
||||
progressListener: QrLoginProgressListenerProxy) async throws -> ClientProtocol {
|
||||
if appSettings.slidingSyncDiscovery == .forceNative {
|
||||
return try await makeClientBuilder(slidingSync: .forceNative).buildWithQrCode(qrCodeData: qrCodeData,
|
||||
oidcConfiguration: oidcConfiguration.rustValue,
|
||||
progressListener: progressListener)
|
||||
}
|
||||
|
||||
if appSettings.slidingSyncDiscovery == .native {
|
||||
do {
|
||||
return try await makeClientBuilder(slidingSync: .discoverNative).buildWithQrCode(qrCodeData: qrCodeData,
|
||||
oidcConfiguration: oidcConfiguration.rustValue,
|
||||
progressListener: progressListener)
|
||||
} catch HumanQrLoginError.SlidingSyncNotAvailable {
|
||||
MXLog.warning("Native sliding sync not available")
|
||||
MXLog.info("Falling back to a sliding sync proxy.")
|
||||
}
|
||||
}
|
||||
|
||||
return try await makeClientBuilder(slidingSync: .discoverProxy).buildWithQrCode(qrCodeData: qrCodeData,
|
||||
oidcConfiguration: oidcConfiguration.rustValue,
|
||||
progressListener: progressListener)
|
||||
try await makeClientBuilder().buildWithQrCode(qrCodeData: qrCodeData,
|
||||
oidcConfiguration: oidcConfiguration.rustValue,
|
||||
progressListener: progressListener)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
/// The base builder configuration used for authentication within the app.
|
||||
private func makeClientBuilder(slidingSync: ClientBuilderSlidingSync) -> ClientBuilder {
|
||||
private func makeClientBuilder() -> ClientBuilder {
|
||||
ClientBuilder
|
||||
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
|
||||
slidingSync: slidingSync,
|
||||
slidingSync: .discover,
|
||||
sessionDelegate: clientSessionDelegate,
|
||||
appHooks: appHooks,
|
||||
enableOnlySignedDeviceIsolationMode: appSettings.enableOnlySignedDeviceIsolationMode,
|
||||
|
||||
@@ -19,7 +19,7 @@ class ClientProxy: ClientProxyProtocol {
|
||||
|
||||
private let mediaLoader: MediaLoaderProtocol
|
||||
private let clientQueue: DispatchQueue
|
||||
|
||||
|
||||
private var roomListService: RoomListService?
|
||||
// periphery: ignore - only for retain
|
||||
private var roomListStateUpdateTaskHandle: TaskHandle?
|
||||
@@ -135,6 +135,7 @@ class ClientProxy: ClientProxyProtocol {
|
||||
private let sendQueueStatusSubject = CurrentValueSubject<Bool, Never>(false)
|
||||
|
||||
init(client: ClientProtocol,
|
||||
needsSlidingSyncMigration: Bool,
|
||||
networkMonitor: NetworkMonitorProtocol,
|
||||
appSettings: AppSettings) async {
|
||||
self.client = client
|
||||
@@ -148,6 +149,8 @@ class ClientProxy: ClientProxyProtocol {
|
||||
notificationSettings = NotificationSettingsProxy(notificationSettings: client.getNotificationSettings())
|
||||
|
||||
secureBackupController = SecureBackupController(encryption: client.encryption())
|
||||
|
||||
self.needsSlidingSyncMigration = needsSlidingSyncMigration
|
||||
|
||||
delegateHandle = client.setDelegate(delegate: ClientDelegateWrapper { [weak self] isSoftLogout in
|
||||
self?.hasEncounteredAuthError = true
|
||||
@@ -221,16 +224,11 @@ class ClientProxy: ClientProxyProtocol {
|
||||
client.homeserver()
|
||||
}
|
||||
|
||||
let needsSlidingSyncMigration: Bool
|
||||
var slidingSyncVersion: SlidingSyncVersion {
|
||||
client.slidingSyncVersion()
|
||||
}
|
||||
|
||||
var availableSlidingSyncVersions: [SlidingSyncVersion] {
|
||||
get async {
|
||||
await client.availableSlidingSyncVersions()
|
||||
}
|
||||
}
|
||||
|
||||
var canDeactivateAccount: Bool {
|
||||
client.canDeactivateAccount()
|
||||
}
|
||||
@@ -263,6 +261,11 @@ 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
|
||||
|
||||
@@ -75,9 +75,11 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
||||
var deviceID: String? { get }
|
||||
|
||||
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 availableSlidingSyncVersions: [SlidingSyncVersion] { get async }
|
||||
|
||||
var canDeactivateAccount: Bool { get }
|
||||
|
||||
|
||||
@@ -112,7 +112,8 @@ class KeychainController: KeychainControllerProtocol {
|
||||
let restorationToken = RestorationToken(session: session,
|
||||
sessionDirectories: oldToken.sessionDirectories,
|
||||
passphrase: oldToken.passphrase,
|
||||
pusherNotificationClientIdentifier: oldToken.pusherNotificationClientIdentifier)
|
||||
pusherNotificationClientIdentifier: oldToken.pusherNotificationClientIdentifier,
|
||||
slidingSyncProxyURLString: oldToken.slidingSyncProxyURLString)
|
||||
setRestorationToken(restorationToken, forUsername: session.userId)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,13 @@ struct RestorationToken: Equatable {
|
||||
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
|
||||
@@ -27,7 +34,7 @@ extension RestorationToken: Codable {
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
let session = try container.decode(MatrixRustSDK.Session.self, forKey: .session)
|
||||
let sessionWrapper = try container.decode(SessionWrapper.self, forKey: .session)
|
||||
let dataDirectory = try container.decodeIfPresent(URL.self, forKey: .sessionDirectory)
|
||||
let cacheDirectory = try container.decodeIfPresent(URL.self, forKey: .cacheDirectory)
|
||||
|
||||
@@ -38,18 +45,19 @@ extension RestorationToken: Codable {
|
||||
SessionDirectories(dataDirectory: dataDirectory)
|
||||
}
|
||||
} else {
|
||||
SessionDirectories(userID: session.userId)
|
||||
SessionDirectories(userID: sessionWrapper.session.userId)
|
||||
}
|
||||
|
||||
self = try .init(session: session,
|
||||
self = try .init(session: sessionWrapper.session,
|
||||
sessionDirectories: sessionDirectories,
|
||||
passphrase: container.decodeIfPresent(String.self, forKey: .passphrase),
|
||||
pusherNotificationClientIdentifier: container.decodeIfPresent(String.self, forKey: .pusherNotificationClientIdentifier))
|
||||
pusherNotificationClientIdentifier: container.decodeIfPresent(String.self, forKey: .pusherNotificationClientIdentifier),
|
||||
slidingSyncProxyURLString: sessionWrapper.slidingSyncProxyURLString)
|
||||
}
|
||||
|
||||
func encode(to encoder: any Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(session, forKey: .session)
|
||||
try container.encode(SessionWrapper(session: session, slidingSyncProxyURLString: slidingSyncProxyURLString), forKey: .session)
|
||||
try container.encode(sessionDirectories.dataDirectory, forKey: .sessionDirectory)
|
||||
try container.encode(sessionDirectories.cacheDirectory, forKey: .cacheDirectory)
|
||||
try container.encode(passphrase, forKey: .passphrase)
|
||||
@@ -57,17 +65,40 @@ 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)
|
||||
let slidingSyncProxy = try container.decodeIfPresent(String.self, forKey: .slidingSyncProxy)
|
||||
self = try .init(accessToken: container.decode(String.self, forKey: .accessToken),
|
||||
refreshToken: container.decodeIfPresent(String.self, forKey: .refreshToken),
|
||||
userId: container.decode(String.self, forKey: .userId),
|
||||
deviceId: container.decode(String.self, forKey: .deviceId),
|
||||
homeserverUrl: container.decode(String.self, forKey: .homeserverUrl),
|
||||
oidcData: container.decodeIfPresent(String.self, forKey: .oidcData),
|
||||
slidingSyncVersion: slidingSyncProxy.map { .proxy(url: $0) } ?? .native)
|
||||
slidingSyncVersion: .native)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@@ -78,17 +109,9 @@ extension MatrixRustSDK.Session: Codable {
|
||||
try container.encode(deviceId, forKey: .deviceId)
|
||||
try container.encode(homeserverUrl, forKey: .homeserverUrl)
|
||||
try container.encode(oidcData, forKey: .oidcData)
|
||||
try container.encode(slidingSyncVersion.proxyURL, forKey: .slidingSyncProxy)
|
||||
}
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case accessToken, refreshToken, userId, deviceId, homeserverUrl, oidcData, slidingSyncProxy
|
||||
}
|
||||
}
|
||||
|
||||
private extension SlidingSyncVersion {
|
||||
var proxyURL: String? {
|
||||
guard case let .proxy(url) = self else { return nil }
|
||||
return url
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,12 +64,13 @@ class UserSessionStore: UserSessionStoreProtocol {
|
||||
do {
|
||||
let session = try client.session()
|
||||
let userID = try client.userId()
|
||||
let clientProxy = await setupProxyForClient(client)
|
||||
let clientProxy = await setupProxyForClient(client, needsSlidingSyncMigration: false)
|
||||
|
||||
keychainController.setRestorationToken(RestorationToken(session: session,
|
||||
sessionDirectories: sessionDirectories,
|
||||
passphrase: passphrase,
|
||||
pusherNotificationClientIdentifier: clientProxy.pusherNotificationClientIdentifier),
|
||||
pusherNotificationClientIdentifier: clientProxy.pusherNotificationClientIdentifier,
|
||||
slidingSyncProxyURLString: nil),
|
||||
forUsername: userID)
|
||||
|
||||
MXLog.info("Set up session for user \(userID) at: \(sessionDirectories)")
|
||||
@@ -145,15 +146,16 @@ class UserSessionStore: UserSessionStoreProtocol {
|
||||
|
||||
MXLog.info("Set up session for user \(credentials.userID) at: \(credentials.restorationToken.sessionDirectories)")
|
||||
|
||||
return await .success(setupProxyForClient(client))
|
||||
return await .success(setupProxyForClient(client, needsSlidingSyncMigration: credentials.restorationToken.needsSlidingSyncMigration))
|
||||
} catch {
|
||||
MXLog.error("Failed restoring login with error: \(error)")
|
||||
return .failure(.failedRestoringLogin)
|
||||
}
|
||||
}
|
||||
|
||||
private func setupProxyForClient(_ client: ClientProtocol) async -> ClientProxyProtocol {
|
||||
private func setupProxyForClient(_ client: ClientProtocol, needsSlidingSyncMigration: Bool) async -> ClientProxyProtocol {
|
||||
await ClientProxy(client: client,
|
||||
needsSlidingSyncMigration: needsSlidingSyncMigration,
|
||||
networkMonitor: networkMonitor,
|
||||
appSettings: appSettings)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user