Validate messages before sending

pull/308/head
nielsandriesse 5 years ago
parent 063214dea3
commit 001b85353e

@ -19,6 +19,9 @@ public final class ClosedGroupUpdate : ControlMessage {
self.kind = kind self.kind = kind
} }
// MARK: Validation
public override var isValidForSending: Bool { kind != nil }
// MARK: Coding // MARK: Coding
public required init?(coder: NSCoder) { public required init?(coder: NSCoder) {
super.init(coder: coder) super.init(coder: coder)

@ -10,6 +10,9 @@ public final class ExpirationTimerUpdate : ControlMessage {
self.duration = duration self.duration = duration
} }
// MARK: Validation
public override var isValidForSending: Bool { duration != nil }
// MARK: Coding // MARK: Coding
public required init?(coder: NSCoder) { public required init?(coder: NSCoder) {
super.init(coder: coder) super.init(coder: coder)

@ -10,6 +10,12 @@ public final class ReadReceipt : ControlMessage {
self.timestamps = timestamps self.timestamps = timestamps
} }
// MARK: Validation
public override var isValidForSending: Bool {
if let timestamps = timestamps, !timestamps.isEmpty { return true }
return false
}
// MARK: Coding // MARK: Coding
public required init?(coder: NSCoder) { public required init?(coder: NSCoder) {
super.init(coder: coder) super.init(coder: coder)

@ -11,6 +11,9 @@ public final class SessionRequest : ControlMessage {
self.preKeyBundle = preKeyBundle self.preKeyBundle = preKeyBundle
} }
// MARK: Validation
public override var isValidForSending: Bool { preKeyBundle != nil }
// MARK: Coding // MARK: Coding
public required init?(coder: NSCoder) { public required init?(coder: NSCoder) {
super.init(coder: coder) super.init(coder: coder)

@ -23,6 +23,9 @@ public final class TypingIndicator : ControlMessage {
} }
} }
// MARK: Validation
public override var isValidForSending: Bool { kind != nil }
// MARK: Initialization // MARK: Initialization
internal init(kind: Kind) { internal init(kind: Kind) {
super.init() super.init()

@ -10,6 +10,9 @@ public class Message : NSObject, NSCoding { // Not a protocol for YapDatabase co
public override init() { } public override init() { }
// MARK: Validation
public var isValidForSending: Bool { true }
// MARK: Coding // MARK: Coding
public required init?(coder: NSCoder) { public required init?(coder: NSCoder) {
if let id = coder.decodeObject(forKey: "id") as! String? { self.id = id } if let id = coder.decodeObject(forKey: "id") as! String? { self.id = id }

@ -12,6 +12,13 @@ public final class VisibleMessage : Message {
// MARK: Initialization // MARK: Initialization
public override init() { super.init() } public override init() { super.init() }
// MARK: Validation
public override var isValidForSending: Bool {
if !attachmentIDs.isEmpty { return true }
if let text = text?.trimmingCharacters(in: .whitespacesAndNewlines), !text.isEmpty { return true }
return false
}
// MARK: Coding // MARK: Coding
public required init?(coder: NSCoder) { public required init?(coder: NSCoder) {
super.init(coder: coder) super.init(coder: coder)

@ -3,6 +3,7 @@ import SessionSnodeKit
import SessionUtilities import SessionUtilities
public enum SendingPipeline { public enum SendingPipeline {
private static let ttl: UInt64 = 2 * 24 * 60 * 60 * 1000
public enum Destination { public enum Destination {
case contact(publicKey: String) case contact(publicKey: String)
@ -11,12 +12,14 @@ public enum SendingPipeline {
} }
public enum Error : LocalizedError { public enum Error : LocalizedError {
case invalidMessage
case protoConversionFailed case protoConversionFailed
case protoSerializationFailed case protoSerializationFailed
case proofOfWorkCalculationFailed case proofOfWorkCalculationFailed
public var errorDescription: String? { public var errorDescription: String? {
switch self { switch self {
case .invalidMessage: return "Invalid message."
case .protoConversionFailed: return "Couldn't convert message to proto." case .protoConversionFailed: return "Couldn't convert message to proto."
case .protoSerializationFailed: return "Couldn't serialize proto." case .protoSerializationFailed: return "Couldn't serialize proto."
case .proofOfWorkCalculationFailed: return "Proof of work calculation failed." case .proofOfWorkCalculationFailed: return "Proof of work calculation failed."
@ -25,19 +28,18 @@ public enum SendingPipeline {
} }
public static func send(_ message: Message, to destination: Destination) -> Promise<Void> { public static func send(_ message: Message, to destination: Destination) -> Promise<Void> {
guard message.isValidForSending else { return Promise(error: Error.invalidMessage) }
guard let proto = message.toProto() else { return Promise(error: Error.protoConversionFailed) } guard let proto = message.toProto() else { return Promise(error: Error.protoConversionFailed) }
let data: Data let plaintext: Data
do { do {
data = try proto.serializedData() plaintext = try proto.serializedData()
} catch { } catch {
SNLog("Couldn't serialize proto due to error: \(error).") SNLog("Couldn't serialize proto due to error: \(error).")
return Promise(error: Error.protoSerializationFailed) return Promise(error: Error.protoSerializationFailed)
} }
// TODO: Encryption let ciphertext = plaintext // TODO: Encryption
// TODO: Validation let recipient = message.recipient!
let recipient = "" let base64EncodedData = ciphertext.base64EncodedString()
let base64EncodedData = data.base64EncodedString()
let ttl: UInt64 = 2 * 24 * 60 * 60 * 1000
guard let (timestamp, nonce) = ProofOfWork.calculate(ttl: ttl, publicKey: recipient, data: base64EncodedData) else { guard let (timestamp, nonce) = ProofOfWork.calculate(ttl: ttl, publicKey: recipient, data: base64EncodedData) else {
SNLog("Proof of work calculation failed.") SNLog("Proof of work calculation failed.")
return Promise(error: Error.proofOfWorkCalculationFailed) return Promise(error: Error.proofOfWorkCalculationFailed)

Loading…
Cancel
Save