Incoming session verification support (#3428)

* Fixes #1227 - Add support for receiving and interacting with incoming session verification requests.
* Fix a couple of random small warnings
* Move static view config to the view state
* Update snapshots
This commit is contained in:
Stefan Ceriu
2024-10-29 15:21:17 +02:00
committed by GitHub
parent cf5e9fb313
commit d77bb935b7
104 changed files with 995 additions and 483 deletions
@@ -50,6 +50,8 @@ class ClientProxy: ClientProxyProtocol {
let secureBackupController: SecureBackupControllerProtocol
private(set) var sessionVerificationController: SessionVerificationControllerProxyProtocol?
private static var roomCreationPowerLevelOverrides: PowerLevels {
.init(usersDefault: nil,
eventsDefault: nil,
@@ -157,7 +159,16 @@ class ClientProxy: ClientProxyProtocol {
updateVerificationState(client.encryption().verificationState())
verificationStateListenerTaskHandle = client.encryption().verificationStateListener(listener: VerificationStateListenerProxy { [weak self] verificationState in
self?.updateVerificationState(verificationState)
guard let self else { return }
updateVerificationState(verificationState)
// The session verification controller requires the user's identity which
// isn't available before a keys query response. Use the verification
// state updates as an aproximation for when that happens.
Task {
await self.buildSessionVerificationControllerProxyIfPossible(verificationState: verificationState)
}
})
sendQueueListenerTaskHandle = client.subscribeToSendQueueStatus(listener: SendQueueRoomErrorListenerProxy { [weak self] roomID, error in
@@ -484,7 +495,8 @@ class ClientProxy: ClientProxyProtocol {
func roomPreviewForIdentifier(_ identifier: String, via: [String]) async -> Result<RoomPreviewDetails, ClientProxyError> {
do {
let roomPreview = try await client.getRoomPreviewFromRoomId(roomId: identifier, viaServers: via)
return .success(.init(roomPreview))
let roomPreviewInfo = try roomPreview.info()
return .success(.init(roomPreviewInfo))
} catch let error as ClientError where error.code == .forbidden {
return .failure(.roomPreviewIsPrivate)
} catch {
@@ -561,16 +573,6 @@ class ClientProxy: ClientProxyProtocol {
}
}
func sessionVerificationControllerProxy() async -> Result<SessionVerificationControllerProxyProtocol, ClientProxyError> {
do {
let sessionVerificationController = try await client.getSessionVerificationController()
return .success(SessionVerificationControllerProxy(sessionVerificationController: sessionVerificationController))
} catch {
MXLog.error("Failed retrieving session verification controller proxy with error: \(error)")
return .failure(.sdkError(error))
}
}
func logout() async -> URL? {
do {
return try await client.logout().flatMap(URL.init(string:))
@@ -728,6 +730,19 @@ class ClientProxy: ClientProxyProtocol {
verificationStateSubject.send(verificationState)
}
private func buildSessionVerificationControllerProxyIfPossible(verificationState: VerificationState) async {
guard sessionVerificationController == nil, verificationState != .unknown else {
return
}
do {
let sessionVerificationController = try await client.getSessionVerificationController()
self.sessionVerificationController = SessionVerificationControllerProxy(sessionVerificationController: sessionVerificationController)
} catch {
MXLog.error("Failed retrieving session verification controller proxy with error: \(error)")
}
}
private func loadUserAvatarURLFromCache() {
loadCachedAvatarURLTask = Task {
@@ -1079,17 +1094,17 @@ private class SendQueueRoomErrorListenerProxy: SendQueueRoomErrorListener {
}
private extension RoomPreviewDetails {
init(_ roomPreview: RoomPreview) {
self = RoomPreviewDetails(roomID: roomPreview.roomId,
name: roomPreview.name,
canonicalAlias: roomPreview.canonicalAlias,
topic: roomPreview.topic,
avatarURL: roomPreview.avatarUrl.flatMap(URL.init(string:)),
memberCount: UInt(roomPreview.numJoinedMembers),
isHistoryWorldReadable: roomPreview.isHistoryWorldReadable,
isJoined: roomPreview.isJoined,
isInvited: roomPreview.isInvited,
isPublic: roomPreview.isPublic,
canKnock: roomPreview.canKnock)
init(_ roomPreviewInfo: RoomPreviewInfo) {
self = RoomPreviewDetails(roomID: roomPreviewInfo.roomId,
name: roomPreviewInfo.name,
canonicalAlias: roomPreviewInfo.canonicalAlias,
topic: roomPreviewInfo.topic,
avatarURL: roomPreviewInfo.avatarUrl.flatMap(URL.init(string:)),
memberCount: UInt(roomPreviewInfo.numJoinedMembers),
isHistoryWorldReadable: roomPreviewInfo.isHistoryWorldReadable,
isJoined: roomPreviewInfo.membership == .joined,
isInvited: roomPreviewInfo.membership == .invited,
isPublic: roomPreviewInfo.joinRule == .public,
canKnock: roomPreviewInfo.joinRule == .knock)
}
}