Implement SessionSnodeKit & SessionProtocolKit conformances
This commit is contained in:
parent
3ef9a50ca6
commit
5d8d468826
|
@ -0,0 +1,7 @@
|
|||
|
||||
extension AppDelegate : SharedSenderKeysDelegate {
|
||||
|
||||
public func requestSenderKey(for groupPublicKey: String, senderPublicKey: String, using transaction: Any) {
|
||||
ClosedGroupsProtocol.requestSenderKey(for: groupPublicKey, senderPublicKey: senderPublicKey, using: transaction as! YapDatabaseReadWriteTransaction)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import SessionProtocolKit
|
||||
import SessionSnodeKit
|
||||
|
||||
@objc(SNConfiguration)
|
||||
final class Configuration : NSObject {
|
||||
|
||||
@objc func performMainSetup() {
|
||||
SessionProtocolKit.configure(storage: Storage.shared, sharedSenderKeysDelegate: UIApplication.shared.delegate as! AppDelegate)
|
||||
SessionSnodeKit.configure(storage: Storage.shared)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
extension Storage : SessionProtocolKitStorageProtocol {
|
||||
|
||||
private func getClosedGroupRatchetCollection(_ collection: ClosedGroupRatchetCollectionType, for groupPublicKey: String) -> String {
|
||||
switch collection {
|
||||
case .old: return "LokiOldClosedGroupRatchetCollection.\(groupPublicKey)"
|
||||
case .current: return "LokiClosedGroupRatchetCollection.\(groupPublicKey)"
|
||||
}
|
||||
}
|
||||
|
||||
public func getClosedGroupRatchet(for groupPublicKey: String, senderPublicKey: String, from collection: ClosedGroupRatchetCollectionType = .current) -> ClosedGroupRatchet? {
|
||||
let collection = getClosedGroupRatchetCollection(collection, for: groupPublicKey)
|
||||
var result: ClosedGroupRatchet?
|
||||
Storage.read { transaction in
|
||||
result = transaction.object(forKey: senderPublicKey, inCollection: collection) as? ClosedGroupRatchet
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func setClosedGroupRatchet(for groupPublicKey: String, senderPublicKey: String, ratchet: ClosedGroupRatchet, in collection: ClosedGroupRatchetCollectionType = .current, using transaction: Any) {
|
||||
let collection = getClosedGroupRatchetCollection(collection, for: groupPublicKey)
|
||||
(transaction as! YapDatabaseReadWriteTransaction).setObject(ratchet, forKey: senderPublicKey, inCollection: collection)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
|
||||
extension Storage : SessionSnodeKitStorageProtocol {
|
||||
|
||||
// MARK: Onion Request Paths
|
||||
internal static let onionRequestPathCollection = "LokiOnionRequestPathCollection"
|
||||
|
||||
public func getOnionRequestPaths() -> [OnionRequestAPI.Path] {
|
||||
let collection = Storage.onionRequestPathCollection
|
||||
var result: [OnionRequestAPI.Path] = []
|
||||
Storage.read { transaction in
|
||||
if
|
||||
let path0Snode0 = transaction.object(forKey: "0-0", inCollection: collection) as? Snode,
|
||||
let path0Snode1 = transaction.object(forKey: "0-1", inCollection: collection) as? Snode,
|
||||
let path0Snode2 = transaction.object(forKey: "0-2", inCollection: collection) as? Snode {
|
||||
result.append([ path0Snode0, path0Snode1, path0Snode2 ])
|
||||
if
|
||||
let path1Snode0 = transaction.object(forKey: "1-0", inCollection: collection) as? Snode,
|
||||
let path1Snode1 = transaction.object(forKey: "1-1", inCollection: collection) as? Snode,
|
||||
let path1Snode2 = transaction.object(forKey: "1-2", inCollection: collection) as? Snode {
|
||||
result.append([ path1Snode0, path1Snode1, path1Snode2 ])
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func setOnionRequestPaths(to paths: [OnionRequestAPI.Path], using transaction: Any) {
|
||||
let collection = Storage.onionRequestPathCollection
|
||||
// FIXME: This approach assumes either 1 or 2 paths of length 3 each. We should do better than this.
|
||||
clearOnionRequestPaths(using: transaction)
|
||||
guard let transaction = transaction as? YapDatabaseReadWriteTransaction else { return }
|
||||
guard paths.count >= 1 else { return }
|
||||
let path0 = paths[0]
|
||||
guard path0.count == 3 else { return }
|
||||
transaction.setObject(path0[0], forKey: "0-0", inCollection: collection)
|
||||
transaction.setObject(path0[1], forKey: "0-1", inCollection: collection)
|
||||
transaction.setObject(path0[2], forKey: "0-2", inCollection: collection)
|
||||
guard paths.count >= 2 else { return }
|
||||
let path1 = paths[1]
|
||||
guard path1.count == 3 else { return }
|
||||
transaction.setObject(path1[0], forKey: "1-0", inCollection: collection)
|
||||
transaction.setObject(path1[1], forKey: "1-1", inCollection: collection)
|
||||
transaction.setObject(path1[2], forKey: "1-2", inCollection: collection)
|
||||
}
|
||||
|
||||
func clearOnionRequestPaths(using transaction: Any) {
|
||||
(transaction as! YapDatabaseReadWriteTransaction).removeAllObjects(inCollection: Storage.onionRequestPathCollection)
|
||||
}
|
||||
|
||||
// MARK: Snode Pool
|
||||
public func getSnodePool() -> Set<Snode> {
|
||||
var result: Set<Snode> = []
|
||||
Storage.read { transaction in
|
||||
transaction.enumerateKeysAndObjects(inCollection: Storage.snodePoolCollection) { _, object, _ in
|
||||
guard let snode = object as? Snode else { return }
|
||||
result.insert(snode)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func setSnodePool(to snodePool: Set<Snode>, using transaction: Any) {
|
||||
clearSnodePool(in: transaction)
|
||||
snodePool.forEach { snode in
|
||||
(transaction as! YapDatabaseReadWriteTransaction).setObject(snode, forKey: snode.description, inCollection: Storage.snodePoolCollection)
|
||||
}
|
||||
}
|
||||
|
||||
func clearSnodePool(in transaction: Any) {
|
||||
(transaction as! YapDatabaseReadWriteTransaction).removeAllObjects(inCollection: Storage.snodePoolCollection)
|
||||
}
|
||||
|
||||
// MARK: Swarm
|
||||
public func getSwarm(for publicKey: String) -> Set<Snode> {
|
||||
var result: Set<Snode> = []
|
||||
let collection = Storage.getSwarmCollection(for: publicKey)
|
||||
Storage.read { transaction in
|
||||
transaction.enumerateKeysAndObjects(inCollection: collection) { _, object, _ in
|
||||
guard let snode = object as? Snode else { return }
|
||||
result.insert(snode)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func setSwarm(to swarm: Set<Snode>, for publicKey: String, using transaction: Any) {
|
||||
clearSwarm(for: publicKey, in: transaction)
|
||||
let collection = Storage.getSwarmCollection(for: publicKey)
|
||||
swarm.forEach { snode in
|
||||
(transaction as! YapDatabaseReadWriteTransaction).setObject(snode, forKey: snode.description, inCollection: collection)
|
||||
}
|
||||
}
|
||||
|
||||
func clearSwarm(for publicKey: String, in transaction: Any) {
|
||||
let collection = Storage.getSwarmCollection(for: publicKey)
|
||||
(transaction as! YapDatabaseReadWriteTransaction).removeAllObjects(inCollection: collection)
|
||||
}
|
||||
|
||||
// MARK: Last Message Hash
|
||||
private static let lastMessageHashCollection = "LokiLastMessageHashCollection"
|
||||
|
||||
func getLastMessageHashInfo(for snode: Snode, associatedWith publicKey: String) -> JSON? {
|
||||
let key = "\(snode.address):\(snode.port).\(publicKey)"
|
||||
var result: JSON?
|
||||
Storage.read { transaction in
|
||||
result = transaction.object(forKey: key, inCollection: Storage.lastMessageHashCollection) as? JSON
|
||||
}
|
||||
if let result = result {
|
||||
guard result["hash"] as? String != nil else { return nil }
|
||||
guard result["expirationDate"] as? NSNumber != nil else { return nil }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func getLastMessageHash(for snode: Snode, associatedWith publicKey: String) -> String? {
|
||||
return getLastMessageHashInfo(for: snode, associatedWith: publicKey)?["hash"] as? String
|
||||
}
|
||||
|
||||
public func setLastMessageHashInfo(for snode: Snode, associatedWith publicKey: String, to lastMessageHashInfo: JSON, using transaction: Any) {
|
||||
let key = "\(snode.address):\(snode.port).\(publicKey)"
|
||||
guard lastMessageHashInfo.count == 2 && lastMessageHashInfo["hash"] as? String != nil && lastMessageHashInfo["expirationDate"] as? NSNumber != nil else { return }
|
||||
(transaction as! YapDatabaseReadWriteTransaction).setObject(lastMessageHashInfo, forKey: key, inCollection: Storage.lastMessageHashCollection)
|
||||
}
|
||||
|
||||
public func pruneLastMessageHashInfoIfExpired(for snode: Snode, associatedWith publicKey: String, using transaction: Any) {
|
||||
guard let lastMessageHashInfo = getLastMessageHashInfo(for: snode, associatedWith: publicKey),
|
||||
(lastMessageHashInfo["hash"] as? String) != nil, let expirationDate = (lastMessageHashInfo["expirationDate"] as? NSNumber)?.uint64Value else { return }
|
||||
let now = NSDate.millisecondTimestamp()
|
||||
if now >= expirationDate {
|
||||
removeLastMessageHashInfo(for: snode, associatedWith: publicKey, using: transaction)
|
||||
}
|
||||
}
|
||||
|
||||
func removeLastMessageHashInfo(for snode: Snode, associatedWith publicKey: String, using transaction: Any) {
|
||||
let key = "\(snode.address):\(snode.port).\(publicKey)"
|
||||
(transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: key, inCollection: Storage.lastMessageHashCollection)
|
||||
}
|
||||
|
||||
// MARK: Received Messages
|
||||
private static let receivedMessagesCollection = "LokiReceivedMessagesCollection"
|
||||
|
||||
public func getReceivedMessages(for publicKey: String) -> Set<String> {
|
||||
var result: Set<String>?
|
||||
Storage.read { transaction in
|
||||
result = transaction.object(forKey: publicKey, inCollection: Storage.receivedMessagesCollection) as? Set<String>
|
||||
}
|
||||
return result ?? []
|
||||
}
|
||||
|
||||
public func setReceivedMessages(to receivedMessages: Set<String>, for publicKey: String, using transaction: Any) {
|
||||
(transaction as! YapDatabaseReadWriteTransaction).setObject(receivedMessages, forKey: publicKey, inCollection: Storage.receivedMessagesCollection)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
extension Storage {
|
||||
|
||||
public static let shared = Storage()
|
||||
|
||||
public func with(_ work: @escaping (Any) -> Void) {
|
||||
Storage.writeSync { work($0) }
|
||||
}
|
||||
|
||||
public func getUserPublicKey() -> String? {
|
||||
return OWSIdentityManager.shared().identityKeyPair()?.publicKey()?.toHexString()
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ public struct Configuration {
|
|||
|
||||
public enum SessionProtocolKit { // Just to make the external API nice
|
||||
|
||||
public static func configure(with configuration: Configuration) {
|
||||
Configuration.shared = configuration
|
||||
public static func configure(storage: SessionProtocolKitStorageProtocol, sharedSenderKeysDelegate: SharedSenderKeysDelegate) {
|
||||
Configuration.shared = Configuration(storage: storage, sharedSenderKeysDelegate: sharedSenderKeysDelegate)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ public enum ClosedGroupRatchetCollectionType {
|
|||
|
||||
public protocol SessionProtocolKitStorageProtocol {
|
||||
|
||||
func with(_ work: (Any) -> Void)
|
||||
func with(_ work: @escaping (Any) -> Void)
|
||||
|
||||
func getClosedGroupRatchet(for groupPublicKey: String, senderPublicKey: String, from collection: ClosedGroupRatchetCollectionType) -> ClosedGroupRatchet?
|
||||
func setClosedGroupRatchet(for groupPublicKey: String, senderPublicKey: String, ratchet: ClosedGroupRatchet, in collection: ClosedGroupRatchetCollectionType, using transaction: Any)
|
||||
|
|
|
@ -7,7 +7,7 @@ public struct Configuration {
|
|||
|
||||
public enum SessionSnodeKit { // Just to make the external API nice
|
||||
|
||||
public static func configure(with configuration: Configuration) {
|
||||
Configuration.shared = configuration
|
||||
public static func configure(storage: SessionSnodeKitStorageProtocol) {
|
||||
Configuration.shared = Configuration(storage: storage)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import SessionUtilitiesKit
|
|||
|
||||
public protocol SessionSnodeKitStorageProtocol {
|
||||
|
||||
func with(_ work: (Any) -> Void)
|
||||
func with(_ work: @escaping (Any) -> Void)
|
||||
|
||||
func getUserPublicKey() -> String?
|
||||
func getOnionRequestPaths() -> [OnionRequestAPI.Path]
|
||||
|
|
|
@ -1188,6 +1188,11 @@
|
|||
C3E5C2FA251DBABB0040DFFC /* EditClosedGroupVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E5C2F9251DBABB0040DFFC /* EditClosedGroupVC.swift */; };
|
||||
C3E7134F251C867C009649BB /* Sodium+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E7134E251C867C009649BB /* Sodium+Conversion.swift */; };
|
||||
C3F0A530255C80BC007BE2A3 /* NoopNotificationsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F0A52F255C80BC007BE2A3 /* NoopNotificationsManager.swift */; };
|
||||
C3F0A5EC255C970D007BE2A3 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F0A5EB255C970D007BE2A3 /* Configuration.swift */; };
|
||||
C3F0A5FE255C988A007BE2A3 /* Storage+Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F0A5FD255C988A007BE2A3 /* Storage+Shared.swift */; };
|
||||
C3F0A608255C98A6007BE2A3 /* Storage+SessionSnodeKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F0A607255C98A6007BE2A3 /* Storage+SessionSnodeKit.swift */; };
|
||||
C3F0A61A255C9902007BE2A3 /* Storage+SessionProtocolKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F0A619255C9902007BE2A3 /* Storage+SessionProtocolKit.swift */; };
|
||||
C3F0A62C255C9937007BE2A3 /* AppDelegate+SharedSenderKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3F0A62B255C9937007BE2A3 /* AppDelegate+SharedSenderKeys.swift */; };
|
||||
D2179CFC16BB0B3A0006F3AB /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2179CFB16BB0B3A0006F3AB /* CoreTelephony.framework */; };
|
||||
D2179CFE16BB0B480006F3AB /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2179CFD16BB0B480006F3AB /* SystemConfiguration.framework */; };
|
||||
D221A08E169C9E5E00537ABF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D221A08D169C9E5E00537ABF /* UIKit.framework */; };
|
||||
|
@ -2579,6 +2584,11 @@
|
|||
C3E7134E251C867C009649BB /* Sodium+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sodium+Conversion.swift"; sourceTree = "<group>"; };
|
||||
C3F0A52F255C80BC007BE2A3 /* NoopNotificationsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoopNotificationsManager.swift; sourceTree = "<group>"; };
|
||||
C3F0A5B2255C915C007BE2A3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
C3F0A5EB255C970D007BE2A3 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = "<group>"; };
|
||||
C3F0A5FD255C988A007BE2A3 /* Storage+Shared.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Storage+Shared.swift"; sourceTree = "<group>"; };
|
||||
C3F0A607255C98A6007BE2A3 /* Storage+SessionSnodeKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Storage+SessionSnodeKit.swift"; sourceTree = "<group>"; };
|
||||
C3F0A619255C9902007BE2A3 /* Storage+SessionProtocolKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Storage+SessionProtocolKit.swift"; sourceTree = "<group>"; };
|
||||
C3F0A62B255C9937007BE2A3 /* AppDelegate+SharedSenderKeys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+SharedSenderKeys.swift"; sourceTree = "<group>"; };
|
||||
C88965DE4F4EC4FC919BEC4E /* Pods-SessionUIKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SessionUIKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SessionUIKit/Pods-SessionUIKit.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
CB3724C70247A916D43271FE /* Pods_Session.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Session.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D2179CFB16BB0B3A0006F3AB /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; };
|
||||
|
@ -4534,6 +4544,11 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
C3F0A58F255C8E3D007BE2A3 /* Meta */,
|
||||
C3F0A62B255C9937007BE2A3 /* AppDelegate+SharedSenderKeys.swift */,
|
||||
C3F0A5EB255C970D007BE2A3 /* Configuration.swift */,
|
||||
C3F0A619255C9902007BE2A3 /* Storage+SessionProtocolKit.swift */,
|
||||
C3F0A607255C98A6007BE2A3 /* Storage+SessionSnodeKit.swift */,
|
||||
C3F0A5FD255C988A007BE2A3 /* Storage+Shared.swift */,
|
||||
B8CCF63B239757C10091D419 /* Components */,
|
||||
C31F812425258F9C00DD9FD9 /* Database */,
|
||||
C32B405424A961E1001117B5 /* Dependencies */,
|
||||
|
@ -6220,6 +6235,7 @@
|
|||
B8CCF63723961D6D0091D419 /* NewPrivateChatVC.swift in Sources */,
|
||||
4CC0B59C20EC5F2E00CF6EE0 /* ConversationConfigurationSyncOperation.swift in Sources */,
|
||||
3461293E1FD1D72B00532771 /* ExperienceUpgradeFinder.swift in Sources */,
|
||||
C3F0A61A255C9902007BE2A3 /* Storage+SessionProtocolKit.swift in Sources */,
|
||||
34C4E2582118957600BEA353 /* WebRTCProto.swift in Sources */,
|
||||
C396DAF12518408B00FF6DC5 /* EnumeratedView.swift in Sources */,
|
||||
34D1F0BD1F8D108C0066283D /* AttachmentUploadView.m in Sources */,
|
||||
|
@ -6311,6 +6327,7 @@
|
|||
C3DFFAC623E96F0D0058DAF8 /* Sheet.swift in Sources */,
|
||||
C31FFE57254A5FFE00F19441 /* KeyPairUtilities.swift in Sources */,
|
||||
45C0DC1E1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */,
|
||||
C3F0A62C255C9937007BE2A3 /* AppDelegate+SharedSenderKeys.swift in Sources */,
|
||||
452ECA4D1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */,
|
||||
45A6DAD61EBBF85500893231 /* ReminderView.swift in Sources */,
|
||||
34D1F0881F8678AA0066283D /* ConversationViewLayout.m in Sources */,
|
||||
|
@ -6333,6 +6350,7 @@
|
|||
4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */,
|
||||
C369549D24D27A3500CEB4E3 /* MultiDeviceRemovalSheet.swift in Sources */,
|
||||
34B6A903218B3F63007C4606 /* TypingIndicatorView.swift in Sources */,
|
||||
C3F0A608255C98A6007BE2A3 /* Storage+SessionSnodeKit.swift in Sources */,
|
||||
458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */,
|
||||
34B6A905218B4C91007C4606 /* TypingIndicatorInteraction.swift in Sources */,
|
||||
2400888E239F30A600305217 /* SessionRestorationView.swift in Sources */,
|
||||
|
@ -6385,11 +6403,13 @@
|
|||
34277A5E20751BDC006049F2 /* OWSQuotedMessageView.m in Sources */,
|
||||
458DE9D61DEE3FD00071BB03 /* PeerConnectionClient.swift in Sources */,
|
||||
45DDA6242090CEB500DE97F8 /* ConversationHeaderView.swift in Sources */,
|
||||
C3F0A5FE255C988A007BE2A3 /* Storage+Shared.swift in Sources */,
|
||||
B82B4090239DD75000A248E7 /* RestoreVC.swift in Sources */,
|
||||
3488F9362191CC4000E524CC /* ConversationMediaView.swift in Sources */,
|
||||
45F32C242057297A00A300D5 /* MessageDetailViewController.swift in Sources */,
|
||||
C396DAEF2518408B00FF6DC5 /* ParsingState.swift in Sources */,
|
||||
3496955C219B605E00DCFE74 /* ImagePickerController.swift in Sources */,
|
||||
C3F0A5EC255C970D007BE2A3 /* Configuration.swift in Sources */,
|
||||
34D1F0841F8678AA0066283D /* ConversationInputToolbar.m in Sources */,
|
||||
457F671B20746193000EABCD /* QuotedReplyPreview.swift in Sources */,
|
||||
C31D1DE32521718E005D4DA8 /* UserSelectionVC.swift in Sources */,
|
||||
|
|
Loading…
Reference in New Issue