This commit is contained in:
nielsandriesse 2020-11-10 15:48:47 +11:00
parent 6986c7db59
commit 82127bfe4d
12 changed files with 55 additions and 23 deletions

View File

@ -2,6 +2,8 @@ import SessionProtocolKit
public struct Configuration {
public let storage: SessionMessagingKitStorageProtocol
public let signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore
public let identityKeyStore: IdentityKeyStore
public let sessionRestorationImplementation: SessionRestorationProtocol
public let certificateValidator: SMKCertificateValidator
public let openGroupAPIDelegate: OpenGroupAPIDelegate
@ -13,7 +15,25 @@ public struct Configuration {
public enum SessionMessagingKit { // Just to make the external API nice
public static func configure(with configuration: Configuration) {
Configuration.shared = configuration
public static func configure(
storage: SessionMessagingKitStorageProtocol,
signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore,
identityKeyStore: IdentityKeyStore,
sessionRestorationImplementation: SessionRestorationProtocol,
certificateValidator: SMKCertificateValidator,
openGroupAPIDelegate: OpenGroupAPIDelegate,
pnServerURL: String,
pnServerPublicKey: String
) {
Configuration.shared = Configuration(
storage: storage,
signalStorage: signalStorage,
identityKeyStore: identityKeyStore,
sessionRestorationImplementation: sessionRestorationImplementation,
certificateValidator: certificateValidator,
openGroupAPIDelegate: openGroupAPIDelegate,
pnServerURL: pnServerURL,
pnServerPublicKey: pnServerPublicKey
)
}
}

View File

@ -1,4 +1,5 @@
@objc(SNJob)
public protocol Job : class {
var delegate: JobDelegate? { get set }
var failureCount: UInt { get set }

View File

@ -1,4 +1,5 @@
@objc(SNJobDelegate)
public protocol JobDelegate {
func handleJobSucceeded(_ job: Job)

View File

@ -1,10 +1,11 @@
import SessionUtilitiesKit
public final class JobQueue : JobDelegate {
@objc(SNJobQueue)
public final class JobQueue : NSObject, JobDelegate {
public static let shared = JobQueue()
@objc public static let shared = JobQueue()
public func add(_ job: Job, using transaction: Any) {
@objc public func add(_ job: Job, using transaction: Any) {
Configuration.shared.storage.persist(job, using: transaction)
job.delegate = self
job.execute()
@ -32,7 +33,7 @@ public final class JobQueue : JobDelegate {
})
} else {
let retryInterval = self.getRetryInterval(for: job)
Timer.weakScheduledTimer(withTimeInterval: retryInterval, target: self, selector: #selector(retry(_:)), userInfo: job, repeats: false)
Timer.weakScheduledTimer(withTimeInterval: retryInterval, target: self, selector: #selector(self.retry(_:)), userInfo: job, repeats: false)
}
})
}

View File

@ -1,5 +1,6 @@
import SessionUtilitiesKit
@objc(SNMessageSendJob)
public final class MessageSendJob : NSObject, Job, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
public var delegate: JobDelegate?
private let message: Message
@ -10,6 +11,9 @@ public final class MessageSendJob : NSObject, Job, NSCoding { // NSObject/NSCodi
public static let maxFailureCount: UInt = 20
// MARK: Initialization
@objc public convenience init(message: Message, publicKey: String) { self.init(message: message, destination: .contact(publicKey: publicKey)) }
@objc public convenience init(message: Message, groupPublicKey: String) { self.init(message: message, destination: .closedGroup(groupPublicKey: groupPublicKey)) }
init(message: Message, destination: Message.Destination) {
self.message = message
self.destination = destination

View File

@ -2,12 +2,12 @@ import SessionUtilitiesKit
@objc(SNVisibleMessage)
public final class VisibleMessage : Message {
public var text: String?
public var attachmentIDs: [String] = []
public var quote: Quote?
public var linkPreview: LinkPreview?
public var contact: Contact?
public var profile: Profile?
@objc public var text: String?
@objc public var attachmentIDs: [String] = []
@objc public var quote: Quote?
@objc public var linkPreview: LinkPreview?
@objc public var contact: Contact?
@objc public var profile: Profile?
// MARK: Initialization
public override init() { super.init() }

View File

@ -5,12 +5,12 @@ import SessionUtilitiesKit
internal extension MessageReceiver {
static func decryptWithSignalProtocol(envelope: SNProtoEnvelope, using transaction: Any) throws -> (plaintext: Data, senderPublicKey: String) {
let storage = Configuration.shared.storage
let storage = Configuration.shared.signalStorage
let certificateValidator = Configuration.shared.certificateValidator
guard let data = envelope.content else { throw Error.noData }
guard let userPublicKey = storage.getUserPublicKey() else { throw Error.noUserPublicKey }
guard let userPublicKey = Configuration.shared.storage.getUserPublicKey() else { throw Error.noUserPublicKey }
let cipher = try SMKSecretSessionCipher(sessionResetImplementation: Configuration.shared.sessionRestorationImplementation,
sessionStore: storage, preKeyStore: storage, signedPreKeyStore: storage, identityStore: storage)
sessionStore: storage, preKeyStore: storage, signedPreKeyStore: storage, identityStore: Configuration.shared.identityKeyStore)
let result = try cipher.throwswrapped_decryptMessage(certificateValidator: certificateValidator, cipherTextData: data,
timestamp: envelope.timestamp, localRecipientId: userPublicKey, localDeviceId: 1, protocolContext: transaction)
return (result.paddedPayload, result.senderRecipientId)

View File

@ -59,6 +59,7 @@ internal enum MessageReceiver {
return nil
}()
if let message = message {
message.receivedTimestamp = NSDate.millisecondTimestamp()
guard message.isValid else { throw Error.invalidMessage }
return message
} else {

View File

@ -4,12 +4,12 @@ import SessionUtilitiesKit
internal extension MessageSender {
static func encryptWithSignalProtocol(_ plaintext: Data, associatedWith message: Message, for publicKey: String, using transaction: Any) throws -> Data {
let storage = Configuration.shared.storage
let storage = Configuration.shared.signalStorage
let cipher = try SMKSecretSessionCipher(sessionResetImplementation: Configuration.shared.sessionRestorationImplementation,
sessionStore: storage, preKeyStore: storage, signedPreKeyStore: storage, identityStore: storage)
sessionStore: storage, preKeyStore: storage, signedPreKeyStore: storage, identityStore: Configuration.shared.identityKeyStore)
let useFallbackEncryption: Bool = {
if (message is SessionRequest) { return true }
return !Configuration.shared.storage.containsSession(publicKey, deviceId: 1, protocolContext: transaction)
return !storage.containsSession(publicKey, deviceId: 1, protocolContext: transaction)
}()
let certificate = Configuration.shared.storage.getSenderCertificate(for: publicKey)
return try cipher.throwswrapped_encryptMessage(recipientPublicKey: publicKey, deviceID: 1, paddedPlaintext: (plaintext as NSData).paddedMessageBody(),

View File

@ -28,6 +28,12 @@ internal enum MessageSender {
}
internal static func sendToSnodeDestination(_ destination: Message.Destination, message: Message, using transaction: Any) -> Promise<Void> {
message.sentTimestamp = NSDate.millisecondTimestamp()
switch destination {
case .contact(let publicKey): message.recipient = publicKey
case .closedGroup(let groupPublicKey): message.recipient = groupPublicKey
case .openGroup(_, _): preconditionFailure()
}
// Validate the message
guard message.isValid else { return Promise(error: Error.invalidMessage) }
// Convert it to protobuf

View File

@ -1,6 +1,6 @@
import SessionProtocolKit
public protocol SessionMessagingKitStorageProtocol : SessionStore, PreKeyStore, SignedPreKeyStore, IdentityKeyStore {
public protocol SessionMessagingKitStorageProtocol {
func with(_ work: (Any) -> Void)
func withAsync(_ work: (Any) -> Void, completion: () -> Void)

View File

@ -2,10 +2,8 @@ import PromiseKit
public extension AnyPromise {
/**
* Sometimes there isn't a straightforward candidate to retain a promise. In that case we tell the
* promise to self retain until it completes, to avoid the risk it's GC'd before completion.
*/
/// Sometimes there isn't a straightforward candidate to retain a promise. In that case we tell the
/// promise to self retain until it completes, to avoid the risk it's GC'd before completion.
@objc
func retainUntilComplete() {
var retainCycle: AnyPromise? = self