Show Encryption Authenticity warnings on messages in the timeline. (#3051)

* Initial implementation.

* Add developer option for showing timeline item authenticity.

* Refactor code to use new SendInfo.Status.

---------

Co-authored-by: Doug <douglase@element.io>
This commit is contained in:
Valere
2024-08-05 13:15:38 +02:00
committed by GitHub
parent cdaa88efcc
commit a11faeb131
29 changed files with 288 additions and 53 deletions
@@ -50,7 +50,11 @@ extension EventBasedTimelineItemProtocol {
var pollIfAvailable: Poll? {
(self as? PollRoomTimelineItem)?.poll
}
var hasStatusIcon: Bool {
hasFailedToSend || properties.encryptionAuthenticity != nil
}
var hasFailedToSend: Bool {
properties.deliveryStatus == .sendingFailed
}
@@ -74,8 +78,8 @@ extension EventBasedTimelineItemProtocol {
whiteSpaces += 1
}
// To account for the extra spacing created by the alert icon
if hasFailedToSend {
// To account for the extra spacing created by the status icon
if hasStatusIcon {
whiteSpaces += 3
}
@@ -24,11 +24,14 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
/// The Matrix ID of the current user.
private let userID: String
private let encryptionAuthenticityEnabled: Bool
init(userID: String,
encryptionAuthenticityEnabled: Bool,
attributedStringBuilder: AttributedStringBuilderProtocol,
stateEventStringBuilder: RoomStateEventStringBuilder) {
self.userID = userID
self.encryptionAuthenticityEnabled = encryptionAuthenticityEnabled
self.attributedStringBuilder = attributedStringBuilder
self.stateEventStringBuilder = stateEventStringBuilder
}
@@ -156,7 +159,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
blurhash: imageInfo.blurhash,
properties: RoomTimelineItemProperties(reactions: aggregateReactions(eventItemProxy.reactions),
deliveryStatus: eventItemProxy.deliveryStatus,
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts)))
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts),
encryptionAuthenticity: authenticity(eventItemProxy.shieldState)))
}
private func buildEncryptedTimelineItem(_ eventItemProxy: EventTimelineItemProxy,
@@ -220,7 +224,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(),
reactions: aggregateReactions(eventItemProxy.reactions),
deliveryStatus: eventItemProxy.deliveryStatus,
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts)))
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts),
encryptionAuthenticity: authenticity(eventItemProxy.shieldState)))
}
private func buildImageTimelineItem(for eventItemProxy: EventTimelineItemProxy,
@@ -240,7 +245,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(),
reactions: aggregateReactions(eventItemProxy.reactions),
deliveryStatus: eventItemProxy.deliveryStatus,
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts)))
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts),
encryptionAuthenticity: authenticity(eventItemProxy.shieldState)))
}
private func buildVideoTimelineItem(for eventItemProxy: EventTimelineItemProxy,
@@ -260,7 +266,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(),
reactions: aggregateReactions(eventItemProxy.reactions),
deliveryStatus: eventItemProxy.deliveryStatus,
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts)))
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts),
encryptionAuthenticity: authenticity(eventItemProxy.shieldState)))
}
private func buildAudioTimelineItem(for eventItemProxy: EventTimelineItemProxy,
@@ -280,7 +287,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(),
reactions: aggregateReactions(eventItemProxy.reactions),
deliveryStatus: eventItemProxy.deliveryStatus,
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts)))
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts),
encryptionAuthenticity: authenticity(eventItemProxy.shieldState)))
}
private func buildVoiceTimelineItem(for eventItemProxy: EventTimelineItemProxy,
@@ -300,7 +308,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(),
reactions: aggregateReactions(eventItemProxy.reactions),
deliveryStatus: eventItemProxy.deliveryStatus,
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts)))
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts),
encryptionAuthenticity: authenticity(eventItemProxy.shieldState)))
}
private func buildFileTimelineItem(for eventItemProxy: EventTimelineItemProxy,
@@ -320,7 +329,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(),
reactions: aggregateReactions(eventItemProxy.reactions),
deliveryStatus: eventItemProxy.deliveryStatus,
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts)))
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts),
encryptionAuthenticity: authenticity(eventItemProxy.shieldState)))
}
private func buildNoticeTimelineItem(for eventItemProxy: EventTimelineItemProxy,
@@ -340,7 +350,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(),
reactions: aggregateReactions(eventItemProxy.reactions),
deliveryStatus: eventItemProxy.deliveryStatus,
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts)))
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts),
encryptionAuthenticity: authenticity(eventItemProxy.shieldState)))
}
private func buildEmoteTimelineItem(for eventItemProxy: EventTimelineItemProxy,
@@ -360,7 +371,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(),
reactions: aggregateReactions(eventItemProxy.reactions),
deliveryStatus: eventItemProxy.deliveryStatus,
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts)))
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts),
encryptionAuthenticity: authenticity(eventItemProxy.shieldState)))
}
private func buildLocationTimelineItem(for eventItemProxy: EventTimelineItemProxy,
@@ -380,7 +392,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(),
reactions: aggregateReactions(eventItemProxy.reactions),
deliveryStatus: eventItemProxy.deliveryStatus,
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts)))
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts),
encryptionAuthenticity: authenticity(eventItemProxy.shieldState)))
}
// swiftlint:disable:next function_parameter_count
@@ -429,7 +442,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
properties: RoomTimelineItemProperties(isEdited: edited,
reactions: aggregateReactions(eventItemProxy.reactions),
deliveryStatus: eventItemProxy.deliveryStatus,
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts)))
orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts),
encryptionAuthenticity: authenticity(eventItemProxy.shieldState)))
}
private func buildCallInviteTimelineItem(for eventItemProxy: EventTimelineItemProxy) -> RoomTimelineItemProtocol {
@@ -488,6 +502,11 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
}
}
private func authenticity(_ shieldState: ShieldState?) -> EncryptionAuthenticity? {
guard encryptionAuthenticityEnabled else { return nil }
return shieldState.flatMap(EncryptionAuthenticity.init)
}
// MARK: - Message events content
private func buildTextTimelineItemContent(_ messageContent: TextMessageContent) -> TextRoomTimelineItemContent {