mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
3.2 KiB
Swift
73 lines
3.2 KiB
Swift
5 years ago
|
|
||
|
public enum MessageWrapper {
|
||
|
|
||
|
public enum Error : LocalizedError {
|
||
|
case failedToWrapData
|
||
|
case failedToWrapMessageInEnvelope
|
||
|
case failedToWrapEnvelopeInWebSocketMessage
|
||
|
case failedToUnwrapData
|
||
|
|
||
|
public var errorDescription: 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: return "Failed to unwrap data."
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Wraps `message` in an `SSKProtoEnvelope` and then a `WebSocketProtoWebSocketMessage` to match the desktop application.
|
||
|
public static func wrap(message: SignalMessage) throws -> Data {
|
||
|
do {
|
||
|
let envelope = try createEnvelope(around: message)
|
||
|
let webSocketMessage = try createWebSocketMessage(around: envelope)
|
||
|
return try webSocketMessage.serializedData()
|
||
|
} catch let error {
|
||
|
throw error as? Error ?? Error.failedToWrapData
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static func createEnvelope(around message: SignalMessage) throws -> SSKProtoEnvelope {
|
||
|
do {
|
||
|
let builder = SSKProtoEnvelope.builder(type: message.type, timestamp: message.timestamp)
|
||
|
builder.setSource(message.senderPublicKey)
|
||
|
builder.setSourceDevice(message.senderDeviceID)
|
||
|
if let content = try Data(base64Encoded: message.content, options: .ignoreUnknownCharacters) {
|
||
|
builder.setContent(content)
|
||
|
} else {
|
||
|
throw Error.failedToWrapMessageInEnvelope
|
||
|
}
|
||
|
return try builder.build()
|
||
|
} catch let error {
|
||
|
print("[Loki] Failed to wrap message in envelope: \(error).")
|
||
|
throw Error.failedToWrapMessageInEnvelope
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static func createWebSocketMessage(around envelope: SSKProtoEnvelope) throws -> WebSocketProtoWebSocketMessage {
|
||
|
do {
|
||
|
let requestBuilder = WebSocketProtoWebSocketRequestMessage.builder(verb: "PUT", path: "/api/v1/message", requestID: UInt64.random(in: 1..<UInt64.max))
|
||
|
requestBuilder.setBody(try envelope.serializedData())
|
||
|
let messageBuilder = WebSocketProtoWebSocketMessage.builder(type: .request)
|
||
|
messageBuilder.setRequest(try requestBuilder.build())
|
||
|
return try messageBuilder.build()
|
||
|
} catch let error {
|
||
|
print("[Loki] Failed to wrap envelope in web socket message: \(error).")
|
||
|
throw Error.failedToWrapEnvelopeInWebSocketMessage
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// - Note: `data` shouldn't be base 64 encoded.
|
||
|
public static func unwrap(data: Data) throws -> SSKProtoEnvelope {
|
||
|
do {
|
||
|
let webSocketMessage = try WebSocketProtoWebSocketMessage.parseData(data)
|
||
|
let envelope = webSocketMessage.request!.body!
|
||
|
return try SSKProtoEnvelope.parseData(envelope)
|
||
|
} catch let error {
|
||
|
print("[Loki] Failed to unwrap data: \(error).")
|
||
|
throw Error.failedToUnwrapData
|
||
|
}
|
||
|
}
|
||
|
}
|