Files
Morgan Pretty a8b266b6c0 Fixed a number of bugs
• Added a few logs to the NotificationServiceExtension where it could potentially end execution without a resolution log being added
• Updated export logs to provide additional debugging information
• Tweaked the logs when failing to unwrap a message
• Tweaked the poller logs
• Fixed an issue where tapping on a "Call Missed" info message with an "(i)" wouldn't show a modal in all cases
• Fixed an issue where group admins couldn't "Clear All Message" only on the current device
• Fixed an issue where community conversations wouldn't have the correct created timestamp when linking devices
2025-12-12 16:14:57 +11:00

99 lines
4.1 KiB
Swift

// stringlint:disable
import Foundation
import SessionNetworkingKit
import SessionUtilitiesKit
public enum MessageWrapperError: Error, CustomStringConvertible {
case failedToWrapData
case failedToWrapMessageInEnvelope
case failedToWrapEnvelopeInWebSocketMessage
case failedToUnwrapData(Error, Network.SnodeAPI.Namespace)
public var description: String {
switch self {
case .failedToWrapData: return "Failed to wrap data."
case .failedToWrapMessageInEnvelope: return "Failed to wrap message in envelope."
case .failedToWrapEnvelopeInWebSocketMessage: return "Failed to wrap envelope in web socket message."
case .failedToUnwrapData(let error, let namespace):
return "Failed to unwrap data from '\(namespace)' namespace due to error: \(error)."
}
}
}
public enum MessageWrapper {
/// Wraps the given parameters in an `SNProtoEnvelope` and then a `WebSocketProtoWebSocketMessage` to match the desktop application.
public static func wrap(
type: SNProtoEnvelope.SNProtoEnvelopeType,
timestampMs: UInt64,
senderPublicKey: String = "", // FIXME: Remove once legacy groups are deprecated
content: Data,
wrapInWebSocketMessage: Bool = true
) throws -> Data {
do {
let envelope: SNProtoEnvelope = try createEnvelope(
type: type,
timestamp: timestampMs,
senderPublicKey: senderPublicKey,
content: content
)
// If we don't want to wrap the message within the `WebSocketProtoWebSocketMessage` type
// the just serialise and return here
guard wrapInWebSocketMessage else { return try envelope.serializedData() }
// Otherwise add the additional wrapper
let webSocketMessage = try createWebSocketMessage(around: envelope)
return try webSocketMessage.serializedData()
} catch let error {
throw error as? MessageWrapperError ?? MessageWrapperError.failedToWrapData
}
}
private static func createEnvelope(type: SNProtoEnvelope.SNProtoEnvelopeType, timestamp: UInt64, senderPublicKey: String, content: Data) throws -> SNProtoEnvelope {
do {
let builder = SNProtoEnvelope.builder(type: type, timestamp: timestamp)
builder.setSource(senderPublicKey)
builder.setSourceDevice(1)
builder.setContent(content)
return try builder.build()
} catch let error {
Log.error(.messageSender, "Failed to wrap message in envelope: \(error).")
throw MessageWrapperError.failedToWrapMessageInEnvelope
}
}
private static func createWebSocketMessage(around envelope: SNProtoEnvelope) throws -> WebSocketProtoWebSocketMessage {
do {
let requestBuilder = WebSocketProtoWebSocketRequestMessage.builder(verb: "", path: "", requestID: 0)
requestBuilder.setBody(try envelope.serializedData())
let messageBuilder = WebSocketProtoWebSocketMessage.builder(type: .request)
messageBuilder.setRequest(try requestBuilder.build())
return try messageBuilder.build()
} catch let error {
Log.error(.messageSender, "Failed to wrap envelope in web socket message: \(error).")
throw MessageWrapperError.failedToWrapEnvelopeInWebSocketMessage
}
}
/// - Note: `data` shouldn't be base 64 encoded.
public static func unwrap(
data: Data,
namespace: Network.SnodeAPI.Namespace,
includesWebSocketMessage: Bool = true
) throws -> SNProtoEnvelope {
do {
let envelopeData: Data = try {
guard includesWebSocketMessage else { return data }
let webSocketMessage = try WebSocketProtoWebSocketMessage.parseData(data)
return webSocketMessage.request!.body!
}()
return try SNProtoEnvelope.parseData(envelopeData)
} catch let error {
throw MessageWrapperError.failedToUnwrapData(error, namespace)
}
}
}