Create MessageSendJob & MessageReceiveJob

Also implement message sending notifications & custom TTL for typing indicators
This commit is contained in:
nielsandriesse 2020-11-08 09:00:10 +11:00
parent 9e42eeca34
commit 4b63588f1a
17 changed files with 225 additions and 54 deletions

View File

@ -0,0 +1,2 @@
public protocol Job { }

View File

@ -0,0 +1,51 @@
import SessionUtilities
public final class MessageReceiveJob : NSObject, Job, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
private let data: Data
private var failureCount: UInt
// MARK: Settings
private static let maxRetryCount: UInt = 20
// MARK: Initialization
init(data: Data) {
self.data = data
self.failureCount = 0
}
// MARK: Coding
public init?(coder: NSCoder) {
guard let data = coder.decodeObject(forKey: "data") as! Data? else { return nil }
self.data = data
self.failureCount = coder.decodeObject(forKey: "failureCount") as! UInt? ?? 0
}
public func encode(with coder: NSCoder) {
coder.encode(data, forKey: "data")
coder.encode(failureCount, forKey: "failureCount")
}
// MARK: Running
public func execute() {
Configuration.shared.storage.with { transaction in // Intentionally capture self
Threading.workQueue.async {
do {
let _ = try MessageReceiver.parse(self.data)
self.handleSuccess()
} catch {
SNLog("Couldn't parse message due to error: \(error).")
self.handleFailure(error: error)
}
}
}
}
private func handleSuccess() {
}
private func handleFailure(error: Error) {
self.failureCount += 1
}
}

View File

@ -0,0 +1,57 @@
import SessionUtilities
// TODO: Destination encoding & decoding
public final class MessageSendJob : NSObject, Job, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
private let message: Message
private let destination: Message.Destination
private var failureCount: UInt
// MARK: Settings
private static let maxRetryCount: UInt = 20
// MARK: Initialization
init(message: Message, destination: Message.Destination) {
self.message = message
self.destination = destination
self.failureCount = 0
}
// MARK: Coding
public init?(coder: NSCoder) {
guard let message = coder.decodeObject(forKey: "message") as! Message?,
let destination = coder.decodeObject(forKey: "destination") as! Message.Destination? else { return nil }
self.message = message
self.destination = destination
self.failureCount = coder.decodeObject(forKey: "failureCount") as! UInt? ?? 0
}
public func encode(with coder: NSCoder) {
coder.encode(message, forKey: "message")
coder.encode(destination, forKey: "destination")
coder.encode(failureCount, forKey: "failureCount")
}
// MARK: Running
public func execute() {
Configuration.shared.storage.with { transaction in // Intentionally capture self
Threading.workQueue.async {
MessageSender.send(self.message, to: self.destination, using: transaction).done(on: Threading.workQueue) {
self.handleSuccess()
}.catch(on: Threading.workQueue) { error in
SNLog("Couldn't send message due to error: \(error).")
self.handleFailure(error: error)
}
}
}
}
private func handleSuccess() {
}
private func handleFailure(error: Error) {
self.failureCount += 1
}
}

View File

@ -4,6 +4,8 @@ import SessionUtilities
public final class TypingIndicator : ControlMessage {
public var kind: Kind?
public override class var ttl: UInt64 { 30 * 1000 }
// MARK: Kind
public enum Kind : String {
case started, stopped

View File

@ -0,0 +1,9 @@
public extension Message {
enum Destination {
case contact(publicKey: String)
case closedGroup(groupPublicKey: String)
case openGroup(channel: UInt64, server: String)
}
}

View File

@ -1,13 +1,15 @@
/// Abstract base class for `VisibleMessage` and `ControlMessage`.
@objc(SNMessage)
public class Message : NSObject, NSCoding { // Not a protocol for YapDatabase compatibility
public class Message : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
public var id: String?
public var threadID: String?
public var sentTimestamp: UInt64?
public var receivedTimestamp: UInt64?
public var recipient: String?
public class var ttl: UInt64 { 2 * 24 * 60 * 60 * 1000 }
public override init() { }
// MARK: Validation

View File

@ -1,9 +0,0 @@
public extension Notification.Name {
static let calculatingPoW = Notification.Name("calculatingPoW")
static let routing = Notification.Name("routing")
static let messageSending = Notification.Name("messageSending")
static let messageSent = Notification.Name("messageSent")
static let messageFailed = Notification.Name("messageFailed")
}

View File

@ -2,7 +2,7 @@ import CryptoSwift
import SessionProtocolKit
import SessionUtilities
public extension ReceivingPipeline {
public extension MessageReceiver {
static func decryptWithSharedSenderKeys(envelope: SNProtoEnvelope, using transaction: Any) throws -> (plaintext: Data, senderPublicKey: String) {
// 1. ) Check preconditions

View File

@ -1,9 +1,10 @@
import SessionUtilities
public enum ReceivingPipeline {
public enum MessageReceiver {
public enum Error : LocalizedError {
case invalidMessage
case unknownMessage
// Shared sender keys
case invalidGroupPublicKey
case noData
@ -14,6 +15,7 @@ public enum ReceivingPipeline {
public var errorDescription: String? {
switch self {
case .invalidMessage: return "Invalid message."
case .unknownMessage: return "Unknown message type."
// Shared sender keys
case .invalidGroupPublicKey: return "Invalid group public key."
case .noData: return "Received an empty envelope."
@ -24,14 +26,14 @@ public enum ReceivingPipeline {
}
}
public static func parse(_ ciphertext: Data) -> Message? {
public static func parse(_ ciphertext: Data) throws -> Message {
let plaintext = ciphertext // TODO: Decryption
let proto: SNProtoContent
do {
proto = try SNProtoContent.parseData(plaintext)
} catch {
SNLog("Couldn't parse proto due to error: \(error).")
return nil
throw error
}
let message: Message? = {
if let readReceipt = ReadReceipt.fromProto(proto) { return readReceipt }
@ -43,10 +45,10 @@ public enum ReceivingPipeline {
return nil
}()
if let message = message {
guard message.isValid else { return nil }
guard message.isValid else { throw Error.invalidMessage }
return message
} else {
return nil
return Error.unknownMessage
}
}
}

View File

@ -1,7 +1,7 @@
import SessionProtocolKit
import SessionUtilities
public extension SendingPipeline {
public extension MessageSender {
static func encryptWithSignalProtocol(_ plaintext: Data, for publicKey: String, using transaction: Any) throws -> Data {
return Data()

View File

@ -2,17 +2,9 @@ import PromiseKit
import SessionSnodeKit
import SessionUtilities
// TODO: Notifications
// TODO: Notify PN server
public enum SendingPipeline {
private static let ttl: UInt64 = 2 * 24 * 60 * 60 * 1000
public enum Destination {
case contact(publicKey: String)
case closedGroup(groupPublicKey: String)
case openGroup(channel: UInt64, server: String)
}
public enum MessageSender {
public enum Error : LocalizedError {
case invalidMessage
@ -30,9 +22,12 @@ public enum SendingPipeline {
}
}
public static func send(_ message: Message, to destination: Destination, using transaction: Any) -> Promise<Void> {
public static func send(_ message: Message, to destination: Message.Destination, using transaction: Any) -> Promise<Void> {
// Validate the message
guard message.isValid else { return Promise(error: Error.invalidMessage) }
// Convert it to protobuf
guard let proto = message.toProto() else { return Promise(error: Error.protoConversionFailed) }
// Serialize the protobuf
let plaintext: Data
do {
plaintext = try proto.serializedData()
@ -40,6 +35,12 @@ public enum SendingPipeline {
SNLog("Couldn't serialize proto due to error: \(error).")
return Promise(error: error)
}
// Encrypt the serialized protobuf
if case .contact(_) = destination {
DispatchQueue.main.async {
NotificationCenter.default.post(name: .encryptingMessage, object: NSNumber(value: message.sentTimestamp!))
}
}
let ciphertext: Data
do {
switch destination {
@ -51,12 +52,24 @@ public enum SendingPipeline {
SNLog("Couldn't encrypt message for destination: \(destination) due to error: \(error).")
return Promise(error: error)
}
// Calculate proof of work
if case .contact(_) = destination {
DispatchQueue.main.async {
NotificationCenter.default.post(name: .calculatingMessagePoW, object: NSNumber(value: message.sentTimestamp!))
}
}
let recipient = message.recipient!
let base64EncodedData = ciphertext.base64EncodedString()
guard let (timestamp, nonce) = ProofOfWork.calculate(ttl: ttl, publicKey: recipient, data: base64EncodedData) else {
SNLog("Proof of work calculation failed.")
return Promise(error: Error.proofOfWorkCalculationFailed)
}
// Send the result
if case .contact(_) = destination {
DispatchQueue.main.async {
NotificationCenter.default.post(name: .messageSending, object: NSNumber(value: message.sentTimestamp!))
}
}
let snodeMessage = SnodeMessage(recipient: recipient, data: base64EncodedData, ttl: ttl, timestamp: timestamp, nonce: nonce)
let (promise, seal) = Promise<Void>.pending()
SnodeAPI.sendMessage(snodeMessage).done(on: Threading.workQueue) { promises in
@ -79,6 +92,16 @@ public enum SendingPipeline {
SNLog("Couldn't send message due to error: \(error).")
seal.reject(error)
}
let _ = promise.done(on: DispatchQueue.main) {
if case .contact(_) = destination {
NotificationCenter.default.post(name: .messageSent, object: NSNumber(value: message.sentTimestamp!))
}
}
let _ = promise.catch(on: DispatchQueue.main) { _ in
if case .contact(_) = destination {
NotificationCenter.default.post(name: .messageSendingFailed, object: NSNumber(value: message.sentTimestamp!))
}
}
return promise
}
}

View File

@ -0,0 +1,9 @@
public extension Notification.Name {
static let encryptingMessage = Notification.Name("encryptingMessage")
static let calculatingMessagePoW = Notification.Name("calculatingPoW")
static let messageSending = Notification.Name("messageSending")
static let messageSent = Notification.Name("messageSent")
static let messageSendingFailed = Notification.Name("messageSendingFailed")
}

View File

@ -1,6 +1,6 @@
import SessionUtilities
public final class ClosedGroupRatchet : NSObject, NSCoding { // Not a struct for YapDatabase compatibility
public final class ClosedGroupRatchet : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
public let chainKey: String
public let keyIndex: UInt
public let messageKeys: [String]

View File

@ -1,5 +1,5 @@
public final class ClosedGroupSenderKey : NSObject, NSCoding { // Not a struct for YapDatabase compatibility
public final class ClosedGroupSenderKey : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
public let chainKey: Data
public let keyIndex: UInt
public let publicKey: Data

View File

@ -137,7 +137,6 @@ public enum OnionRequestAPI {
}
}.map2 { paths in
OnionRequestAPI.paths = paths + reusablePaths
Configuration.shared.storage.with { transaction in
SNLog("Persisting onion request paths to database.")
Configuration.shared.storage.setOnionRequestPaths(to: paths, using: transaction)

View File

@ -1,6 +1,6 @@
import Foundation
public final class Snode : NSObject, NSCoding { // Not a struct for YapDatabase compatibility
public final class Snode : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
public let address: String
public let port: UInt16
internal let publicKeySet: KeySet

View File

@ -573,8 +573,8 @@
C300A5D32554B05A00555489 /* TypingIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5D22554B05A00555489 /* TypingIndicator.swift */; };
C300A5DD2554B06600555489 /* ClosedGroupUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5DC2554B06600555489 /* ClosedGroupUpdate.swift */; };
C300A5E72554B07300555489 /* ExpirationTimerUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5E62554B07300555489 /* ExpirationTimerUpdate.swift */; };
C300A5F22554B09800555489 /* SendingPipeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5F12554B09800555489 /* SendingPipeline.swift */; };
C300A5FC2554B0A000555489 /* ReceivingPipeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5FB2554B0A000555489 /* ReceivingPipeline.swift */; };
C300A5F22554B09800555489 /* MessageSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5F12554B09800555489 /* MessageSender.swift */; };
C300A5FC2554B0A000555489 /* MessageReceiver.swift in Sources */ = {isa = PBXBuildFile; fileRef = C300A5FB2554B0A000555489 /* MessageReceiver.swift */; };
C300A60D2554B31900555489 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5CE2553860700C340D1 /* Logging.swift */; };
C300A6322554B6D100555489 /* NSDate+Timestamp.mm in Sources */ = {isa = PBXBuildFile; fileRef = C300A6312554B6D100555489 /* NSDate+Timestamp.mm */; };
C300A63B2554B72200555489 /* NSDate+Timestamp.h in Headers */ = {isa = PBXBuildFile; fileRef = C300A6302554B68200555489 /* NSDate+Timestamp.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -588,14 +588,18 @@
C31FFE57254A5FFE00F19441 /* KeyPairUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31FFE56254A5FFE00F19441 /* KeyPairUtilities.swift */; };
C329FEEC24F7277900B1C64C /* LightModeSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C329FEEB24F7277900B1C64C /* LightModeSheet.swift */; };
C329FEEF24F7743F00B1C64C /* UIViewController+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C329FEED24F7742E00B1C64C /* UIViewController+Utilities.swift */; };
C3471ECB2555356A00297E91 /* SendingPipeline+Encryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471ECA2555356A00297E91 /* SendingPipeline+Encryption.swift */; };
C3471ECB2555356A00297E91 /* MessageSender+Encryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471ECA2555356A00297E91 /* MessageSender+Encryption.swift */; };
C3471ED42555386B00297E91 /* AESGCM.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5D72553860B00C340D1 /* AESGCM.swift */; };
C3471F4225553A4D00297E91 /* Threading.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471F4125553A4D00297E91 /* Threading.swift */; };
C3471F4C25553AB000297E91 /* ReceivingPipeline+Decryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471F4B25553AB000297E91 /* ReceivingPipeline+Decryption.swift */; };
C3471F4C25553AB000297E91 /* MessageReceiver+Decryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471F4B25553AB000297E91 /* MessageReceiver+Decryption.swift */; };
C3471F5625553E1100297E91 /* ECKeyPair+Utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = C3471F5525553DA000297E91 /* ECKeyPair+Utilities.h */; settings = {ATTRIBUTES = (Public, ); }; };
C3471F6825553E7600297E91 /* ECKeyPair+Utilities.m in Sources */ = {isa = PBXBuildFile; fileRef = C3471F6725553E7600297E91 /* ECKeyPair+Utilities.m */; };
C3471FA42555439E00297E91 /* Notification+SendingPipeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471FA32555439E00297E91 /* Notification+SendingPipeline.swift */; };
C3471FA42555439E00297E91 /* Notification+MessageSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471FA32555439E00297E91 /* Notification+MessageSender.swift */; };
C34C8F7423A7830B00D82669 /* SpaceMono-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C34C8F7323A7830A00D82669 /* SpaceMono-Bold.ttf */; };
C352A2F525574B4700338F3E /* Job.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352A2F425574B4700338F3E /* Job.swift */; };
C352A2FF25574B6300338F3E /* MessageSendJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352A2FE25574B6300338F3E /* MessageSendJob.swift */; };
C352A30925574D8500338F3E /* Message+Destination.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352A30825574D8400338F3E /* Message+Destination.swift */; };
C352A31325574F5200338F3E /* MessageReceiveJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352A31225574F5200338F3E /* MessageReceiveJob.swift */; };
C353F8F9244809150011121A /* PNOptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C353F8F8244809150011121A /* PNOptionView.swift */; };
C3548F0624456447009433A8 /* PNModeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3548F0524456447009433A8 /* PNModeVC.swift */; };
C3548F0824456AB6009433A8 /* UIView+Wrapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3548F0724456AB6009433A8 /* UIView+Wrapping.swift */; };
@ -1574,8 +1578,8 @@
C300A5D22554B05A00555489 /* TypingIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypingIndicator.swift; sourceTree = "<group>"; };
C300A5DC2554B06600555489 /* ClosedGroupUpdate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClosedGroupUpdate.swift; sourceTree = "<group>"; };
C300A5E62554B07300555489 /* ExpirationTimerUpdate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpirationTimerUpdate.swift; sourceTree = "<group>"; };
C300A5F12554B09800555489 /* SendingPipeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendingPipeline.swift; sourceTree = "<group>"; };
C300A5FB2554B0A000555489 /* ReceivingPipeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReceivingPipeline.swift; sourceTree = "<group>"; };
C300A5F12554B09800555489 /* MessageSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSender.swift; sourceTree = "<group>"; };
C300A5FB2554B0A000555489 /* MessageReceiver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageReceiver.swift; sourceTree = "<group>"; };
C300A6302554B68200555489 /* NSDate+Timestamp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDate+Timestamp.h"; sourceTree = "<group>"; };
C300A6312554B6D100555489 /* NSDate+Timestamp.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDate+Timestamp.mm"; sourceTree = "<group>"; };
C31A6C59247F214E001123EF /* UIView+Glow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Glow.swift"; sourceTree = "<group>"; };
@ -1588,13 +1592,17 @@
C31FFE56254A5FFE00F19441 /* KeyPairUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPairUtilities.swift; sourceTree = "<group>"; };
C329FEEB24F7277900B1C64C /* LightModeSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LightModeSheet.swift; sourceTree = "<group>"; };
C329FEED24F7742E00B1C64C /* UIViewController+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Utilities.swift"; sourceTree = "<group>"; };
C3471ECA2555356A00297E91 /* SendingPipeline+Encryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SendingPipeline+Encryption.swift"; sourceTree = "<group>"; };
C3471ECA2555356A00297E91 /* MessageSender+Encryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageSender+Encryption.swift"; sourceTree = "<group>"; };
C3471F4125553A4D00297E91 /* Threading.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Threading.swift; sourceTree = "<group>"; };
C3471F4B25553AB000297E91 /* ReceivingPipeline+Decryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ReceivingPipeline+Decryption.swift"; sourceTree = "<group>"; };
C3471F4B25553AB000297E91 /* MessageReceiver+Decryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageReceiver+Decryption.swift"; sourceTree = "<group>"; };
C3471F5525553DA000297E91 /* ECKeyPair+Utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ECKeyPair+Utilities.h"; sourceTree = "<group>"; };
C3471F6725553E7600297E91 /* ECKeyPair+Utilities.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "ECKeyPair+Utilities.m"; sourceTree = "<group>"; };
C3471FA32555439E00297E91 /* Notification+SendingPipeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+SendingPipeline.swift"; sourceTree = "<group>"; };
C3471FA32555439E00297E91 /* Notification+MessageSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+MessageSender.swift"; sourceTree = "<group>"; };
C34C8F7323A7830A00D82669 /* SpaceMono-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SpaceMono-Bold.ttf"; sourceTree = "<group>"; };
C352A2F425574B4700338F3E /* Job.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Job.swift; sourceTree = "<group>"; };
C352A2FE25574B6300338F3E /* MessageSendJob.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSendJob.swift; sourceTree = "<group>"; };
C352A30825574D8400338F3E /* Message+Destination.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Message+Destination.swift"; sourceTree = "<group>"; };
C352A31225574F5200338F3E /* MessageReceiveJob.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageReceiveJob.swift; sourceTree = "<group>"; };
C353F8F8244809150011121A /* PNOptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PNOptionView.swift; sourceTree = "<group>"; };
C3548F0524456447009433A8 /* PNModeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PNModeVC.swift; sourceTree = "<group>"; };
C3548F0724456AB6009433A8 /* UIView+Wrapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Wrapping.swift"; sourceTree = "<group>"; };
@ -3171,6 +3179,7 @@
isa = PBXGroup;
children = (
C3C2A74325539EB700C340D1 /* Message.swift */,
C352A30825574D8400338F3E /* Message+Destination.swift */,
C300A5C62554B02D00555489 /* Visible Message */,
C300A5C72554B03900555489 /* Control Message */,
);
@ -3202,16 +3211,16 @@
path = "Control Message";
sourceTree = "<group>";
};
C300A5F02554B08500555489 /* Pipelines */ = {
C300A5F02554B08500555489 /* Sending & Receiving */ = {
isa = PBXGroup;
children = (
C3471FA32555439E00297E91 /* Notification+SendingPipeline.swift */,
C300A5F12554B09800555489 /* SendingPipeline.swift */,
C3471ECA2555356A00297E91 /* SendingPipeline+Encryption.swift */,
C300A5FB2554B0A000555489 /* ReceivingPipeline.swift */,
C3471F4B25553AB000297E91 /* ReceivingPipeline+Decryption.swift */,
C3471FA32555439E00297E91 /* Notification+MessageSender.swift */,
C300A5F12554B09800555489 /* MessageSender.swift */,
C3471ECA2555356A00297E91 /* MessageSender+Encryption.swift */,
C300A5FB2554B0A000555489 /* MessageReceiver.swift */,
C3471F4B25553AB000297E91 /* MessageReceiver+Decryption.swift */,
);
path = Pipelines;
path = "Sending & Receiving";
sourceTree = "<group>";
};
C31F812425258F9C00DD9FD9 /* Database */ = {
@ -3231,6 +3240,16 @@
path = Dependencies;
sourceTree = "<group>";
};
C352A2F325574B3300338F3E /* Jobs */ = {
isa = PBXGroup;
children = (
C352A2F425574B4700338F3E /* Job.swift */,
C352A2FE25574B6300338F3E /* MessageSendJob.swift */,
C352A31225574F5200338F3E /* MessageReceiveJob.swift */,
);
path = Jobs;
sourceTree = "<group>";
};
C35E8AA42485C83B00ACB629 /* CSV */ = {
isa = PBXGroup;
children = (
@ -3349,7 +3368,8 @@
C3BBE0752554CDA60050F1E3 /* Configuration.swift */,
C3BBE07F2554CDD70050F1E3 /* Storage.swift */,
C300A5BB2554AFFB00555489 /* Messages */,
C300A5F02554B08500555489 /* Pipelines */,
C300A5F02554B08500555489 /* Sending & Receiving */,
C352A2F325574B3300338F3E /* Jobs */,
C3BBE0B32554F0D30050F1E3 /* Utilities */,
);
path = SessionMessagingKit;
@ -4907,13 +4927,14 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C3471F4C25553AB000297E91 /* ReceivingPipeline+Decryption.swift in Sources */,
C3471F4C25553AB000297E91 /* MessageReceiver+Decryption.swift in Sources */,
C300A5D32554B05A00555489 /* TypingIndicator.swift in Sources */,
C3471ECB2555356A00297E91 /* SendingPipeline+Encryption.swift in Sources */,
C300A5F22554B09800555489 /* SendingPipeline.swift in Sources */,
C3471ECB2555356A00297E91 /* MessageSender+Encryption.swift in Sources */,
C300A5F22554B09800555489 /* MessageSender.swift in Sources */,
C3C2A74D2553A39700C340D1 /* VisibleMessage.swift in Sources */,
C352A31325574F5200338F3E /* MessageReceiveJob.swift in Sources */,
C3C2A7562553A3AB00C340D1 /* VisibleMessage+Quote.swift in Sources */,
C300A5FC2554B0A000555489 /* ReceivingPipeline.swift in Sources */,
C300A5FC2554B0A000555489 /* MessageReceiver.swift in Sources */,
C3BBE0B52554F0E10050F1E3 /* ProofOfWork.swift in Sources */,
C3BBE0802554CDD70050F1E3 /* Storage.swift in Sources */,
C3C2A7842553AAF300C340D1 /* SNProto.swift in Sources */,
@ -4924,13 +4945,16 @@
C3BBE0762554CDA60050F1E3 /* Configuration.swift in Sources */,
C3471F4225553A4D00297E91 /* Threading.swift in Sources */,
C300A5DD2554B06600555489 /* ClosedGroupUpdate.swift in Sources */,
C3471FA42555439E00297E91 /* Notification+SendingPipeline.swift in Sources */,
C3471FA42555439E00297E91 /* Notification+MessageSender.swift in Sources */,
C352A30925574D8500338F3E /* Message+Destination.swift in Sources */,
C300A5E72554B07300555489 /* ExpirationTimerUpdate.swift in Sources */,
C352A2FF25574B6300338F3E /* MessageSendJob.swift in Sources */,
C3C2A75F2553A3C500C340D1 /* VisibleMessage+LinkPreview.swift in Sources */,
C3C2A74425539EB700C340D1 /* Message.swift in Sources */,
C300A5C92554B04E00555489 /* SessionRequest.swift in Sources */,
C3BBE0C72554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift in Sources */,
C300A5B22554AF9800555489 /* VisibleMessage+Profile.swift in Sources */,
C352A2F525574B4700338F3E /* Job.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};