diff --git a/SignalServiceKit/src/Loki/API/Multi Device/LokiDeviceLinkingSession.swift b/SignalServiceKit/src/Loki/API/Multi Device/LokiDeviceLinkingSession.swift index 98be7bc83..8ea44a570 100644 --- a/SignalServiceKit/src/Loki/API/Multi Device/LokiDeviceLinkingSession.swift +++ b/SignalServiceKit/src/Loki/API/Multi Device/LokiDeviceLinkingSession.swift @@ -17,7 +17,7 @@ public final class LokiDeviceLinkingSession : NSObject { @objc public func processLinkingRequest(from slaveHexEncodedPublicKey: String, with slaveSignature: Data) { guard isListeningForLinkingRequests else { return } - isListeningForLinkingRequests = false + stopListeningForLinkingRequests() let master = LokiDeviceLink.Device(hexEncodedPublicKey: OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey) let slave = LokiDeviceLink.Device(hexEncodedPublicKey: slaveHexEncodedPublicKey, signature: slaveSignature) let deviceLink = LokiDeviceLink(between: master, and: slave) @@ -25,6 +25,10 @@ public final class LokiDeviceLinkingSession : NSObject { delegate.requestUserAuthorization(for: deviceLink) } + @objc public func stopListeningForLinkingRequests() { + isListeningForLinkingRequests = false + } + @objc public func authorizeDeviceLink(_ deviceLink: LokiDeviceLink) { // TODO: Send a device link authorized message } diff --git a/SignalServiceKit/src/Loki/Database/DeviceLinkIndex.swift b/SignalServiceKit/src/Loki/Database/DeviceLinkIndex.swift new file mode 100644 index 000000000..896746025 --- /dev/null +++ b/SignalServiceKit/src/Loki/Database/DeviceLinkIndex.swift @@ -0,0 +1,40 @@ + +@objc(LKDeviceLinkIndex) +public final class DeviceLinkIndex : NSObject { + + private static let name = "loki_device_link_index" + + @objc public static let masterHexEncodedPublicKey = "master_hex_encoded_public_key" + @objc public static let slaveHexEncodedPublicKey = "slave_hex_encoded_public_key" + @objc public static let isAuthorized = "is_authorized" + + @objc public static let indexDatabaseExtension: YapDatabaseSecondaryIndex = { + let setup = YapDatabaseSecondaryIndexSetup() + setup.addColumn(masterHexEncodedPublicKey, with: .text) + setup.addColumn(slaveHexEncodedPublicKey, with: .text) + setup.addColumn(isAuthorized, with: .integer) + let handler = YapDatabaseSecondaryIndexHandler.withObjectBlock { _, map, _, _, object in + guard let deviceLink = object as? LokiDeviceLink else { return } + map[masterHexEncodedPublicKey] = deviceLink.master.hexEncodedPublicKey + map[slaveHexEncodedPublicKey] = deviceLink.slave.hexEncodedPublicKey + map[isAuthorized] = deviceLink.isAuthorized + } + return YapDatabaseSecondaryIndex(setup: setup, handler: handler) + }() + + @objc public static var databaseExtensionName: String { return name } + + @objc public static func asyncRegisterDatabaseExtensions(_ storage: OWSStorage) { + storage.register(indexDatabaseExtension, withName: name) + } + + @objc public static func getDeviceLinks(for query: YapDatabaseQuery, in transaction: YapDatabaseReadTransaction) -> [LokiDeviceLink] { + guard let ext = transaction.ext(DeviceLinkIndex.name) as? YapDatabaseSecondaryIndexTransaction else { return [] } + var result: [LokiDeviceLink] = [] + ext.enumerateKeysAndObjects(matching: query) { _, _, object, _ in + guard let deviceLink = object as? LokiDeviceLink else { return } + result.append(deviceLink) + } + return result + } +} diff --git a/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift b/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift index 405eba4ec..57e73015d 100644 --- a/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift +++ b/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift @@ -1,6 +1,10 @@ extension OWSPrimaryStorage { + private func getCollection(for primaryDevice: String) -> String { + return "LokiDeviceLinkCollection-\(primaryDevice)" + } + public func storeDeviceLink(_ deviceLink: LokiDeviceLink, in transaction: YapDatabaseReadWriteTransaction) { let collection = getCollection(for: deviceLink.master.hexEncodedPublicKey) transaction.setObject(deviceLink, forKey: deviceLink.slave.hexEncodedPublicKey, inCollection: collection) @@ -16,7 +20,13 @@ extension OWSPrimaryStorage { return result } - private func getCollection(for primaryDevice: String) -> String { - return "LokiDeviceLinkCollection-\(primaryDevice)" + public func getDeviceLink(for slaveHexEncodedPublicKey: String, in transaction: YapDatabaseReadTransaction) -> LokiDeviceLink? { + let query = YapDatabaseQuery(string: "WHERE \(DeviceLinkIndex.slaveHexEncodedPublicKey) = ?", parameters: [ slaveHexEncodedPublicKey ]) + let deviceLinks = DeviceLinkIndex.getDeviceLinks(for: query, in: transaction) + guard deviceLinks.count <= 1 else { + print("[Loki] Found multiple device links for slave hex encoded public key: \(slaveHexEncodedPublicKey).") + return nil + } + return deviceLinks.first } } diff --git a/SignalServiceKit/src/Loki/Database/PairingAuthorisationsIndex.swift b/SignalServiceKit/src/Loki/Database/PairingAuthorisationsIndex.swift deleted file mode 100644 index 4413a9cc5..000000000 --- a/SignalServiceKit/src/Loki/Database/PairingAuthorisationsIndex.swift +++ /dev/null @@ -1,53 +0,0 @@ -//@objc(LKPairingAuthorisationsIndex) -//public final class PairingAuthorisationsIndex : NSObject { -// private static let name = "loki_index_pairing_authorisations" -// -// // Fields -// @objc public static let primaryDevicePubKey = "pairing_primary_device_pub_key" -// @objc public static let secondaryDevicePubKey = "pairing_secondary_device_pub_key" -// @objc public static let isGranted = "pairing_is_granted" -// -// // MARK: Database Extension -// -// @objc public static var indexDatabaseExtension: YapDatabaseSecondaryIndex { -// let setup = YapDatabaseSecondaryIndexSetup() -// setup.addColumn(primaryDevicePubKey, with: .text) -// setup.addColumn(secondaryDevicePubKey, with: .text) -// setup.addColumn(isGranted, with: .integer) -// -// let handler = YapDatabaseSecondaryIndexHandler.withObjectBlock { (transaction, dict, collection, key, object) in -// guard let pairing = object as? LokiPairingAuthorisation else { return } -// dict[primaryDevicePubKey] = pairing.primaryDevicePubKey -// dict[secondaryDevicePubKey] = pairing.secondaryDevicePubKey -// dict[isGranted] = pairing.isGranted -// } -// -// return YapDatabaseSecondaryIndex(setup: setup, handler: handler) -// } -// -// @objc public static var databaseExtensionName: String { -// return name -// } -// -// @objc public static func asyncRegisterDatabaseExtensions(_ storage: OWSStorage) { -// storage.register(indexDatabaseExtension, withName: name) -// } -// -// // MARK: Helper -// -// public static func enumeratePairingAuthorisations(with query: YapDatabaseQuery, transaction: YapDatabaseReadTransaction, block: @escaping (LokiPairingAuthorisation, UnsafeMutablePointer) -> Void) { -// let ext = transaction.ext(PairingAuthorisationsIndex.name) as? YapDatabaseSecondaryIndexTransaction -// ext?.enumerateKeysAndObjects(matching: query) { (collection, key, object, stop) in -// guard let authorisation = object as? LokiPairingAuthorisation else { return } -// block(authorisation, stop) -// } -// } -// -// public static func getPairingAuthorisations(with query: YapDatabaseQuery, transaction: YapDatabaseReadTransaction) -> [LokiPairingAuthorisation] { -// var authorisations = [LokiPairingAuthorisation]() -// enumeratePairingAuthorisations(with: query, transaction: transaction) { (authorisation, _) in -// authorisations.append(authorisation) -// } -// return authorisations -// } -//}