From 99c473ee345234c6297ee6d5517d075cc7695abb Mon Sep 17 00:00:00 2001 From: gmbnt Date: Wed, 25 Mar 2020 15:52:25 +1100 Subject: [PATCH 01/10] Use only updated snodes for file server proxying --- .../src/Loki/API/LokiAPI+SwarmAPI.swift | 39 +++++++++++++++++-- SignalServiceKit/src/Loki/API/LokiAPI.swift | 1 + .../src/Loki/API/LokiFileServerProxy.swift | 2 +- .../src/Network/OWSSignalService.m | 3 ++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift index 50d363008..29e2febbb 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift @@ -1,14 +1,14 @@ import PromiseKit public extension LokiAPI { + private static var snodeVersion: [LokiAPITarget:String] = [:] /// Only ever accessed from `LokiAPI.errorHandlingQueue` to avoid race conditions. fileprivate static var failureCount: [LokiAPITarget:UInt] = [:] - + // MARK: Settings private static let minimumSnodeCount = 2 private static let targetSnodeCount = 3 - private static let maxRandomSnodePoolSize = 1024 fileprivate static let failureThreshold = 2 // MARK: Caching @@ -84,11 +84,44 @@ public extension LokiAPI { } } - // MARK: Public API internal static func getTargetSnodes(for hexEncodedPublicKey: String) -> Promise<[LokiAPITarget]> { // shuffled() uses the system's default random generator, which is cryptographically secure return getSwarm(for: hexEncodedPublicKey).map { Array($0.shuffled().prefix(targetSnodeCount)) } } + + internal static func getFileServerProxy() -> Promise { + let (promise, seal) = Promise.pending() + func getVersion(for snode: LokiAPITarget) -> Promise { + let url = URL(string: "\(snode.address):\(snode.port)/get_stats/v1")! + let request = TSRequest(url: url) + if let version = snodeVersion[snode] { + return Promise { $0.fulfill(version) } + } else { + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map(on: DispatchQueue.global()) { intermediate in + let rawResponse = intermediate.responseObject + guard let json = rawResponse as? JSON, let version = json["version"] as? String else { throw LokiAPIError.missingSnodeVersion } + snodeVersion[snode] = version + return version + } + } + } + getRandomSnode().done(on: DispatchQueue.global()) { snode in + getVersion(for: snode).then(on: DispatchQueue.global()) { version -> Promise in + if version >= "2.0.2" { + print("[Loki] Using file server proxy with version number \(version).") + return Promise { $0.fulfill(snode) } + } else { + print("[Loki] Rejecting file server proxy with version number \(version).") + return getFileServerProxy() + } + }.recover(on: DispatchQueue.global()) { error in + return getFileServerProxy() + } + }.catch(on: DispatchQueue.global()) { error in + seal.reject(error) + } + return promise + } // MARK: Parsing private static func parseTargets(from rawResponse: Any) -> [LokiAPITarget] { diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index 020979087..ea60e5440 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -47,6 +47,7 @@ public final class LokiAPI : NSObject { @objc public static let messageConversionFailed = LokiAPIError(domain: "LokiAPIErrorDomain", code: 2, userInfo: [ NSLocalizedDescriptionKey : "Failed to construct message." ]) @objc public static let clockOutOfSync = LokiAPIError(domain: "LokiAPIErrorDomain", code: 3, userInfo: [ NSLocalizedDescriptionKey : "Your clock is out of sync with the service node network." ]) @objc public static let randomSnodePoolUpdatingFailed = LokiAPIError(domain: "LokiAPIErrorDomain", code: 4, userInfo: [ NSLocalizedDescriptionKey : "Failed to update random service node pool." ]) + @objc public static let missingSnodeVersion = LokiAPIError(domain: "LokiAPIErrorDomain", code: 5, userInfo: [ NSLocalizedDescriptionKey : "Missing service node version." ]) } @objc(LKDestination) diff --git a/SignalServiceKit/src/Loki/API/LokiFileServerProxy.swift b/SignalServiceKit/src/Loki/API/LokiFileServerProxy.swift index a291edcf0..76463b711 100644 --- a/SignalServiceKit/src/Loki/API/LokiFileServerProxy.swift +++ b/SignalServiceKit/src/Loki/API/LokiFileServerProxy.swift @@ -50,7 +50,7 @@ internal class LokiFileServerProxy : LokiHTTPClient { DispatchQueue.global().async { let uncheckedSymmetricKey = try? Curve25519.generateSharedSecret(fromPublicKey: LokiFileServerProxy.fileServerPublicKey, privateKey: keyPair.privateKey) guard let symmetricKey = uncheckedSymmetricKey else { return seal.reject(Error.symmetricKeyGenerationFailed) } - LokiAPI.getRandomSnode().then(on: DispatchQueue.global()) { proxy -> Promise in + LokiAPI.getFileServerProxy().then(on: DispatchQueue.global()) { proxy -> Promise in let url = "\(proxy.address):\(proxy.port)/file_proxy" guard let urlAsString = request.url?.absoluteString, let serverURLEndIndex = urlAsString.range(of: server)?.upperBound, serverURLEndIndex < urlAsString.endIndex else { throw Error.endpointParsingFailed } diff --git a/SignalServiceKit/src/Network/OWSSignalService.m b/SignalServiceKit/src/Network/OWSSignalService.m index 57498b2fc..4cd89785d 100644 --- a/SignalServiceKit/src/Network/OWSSignalService.m +++ b/SignalServiceKit/src/Network/OWSSignalService.m @@ -194,6 +194,9 @@ NSString *const kNSNotificationName_IsCensorshipCircumventionActiveDidChange = sessionManager.requestSerializer = [AFJSONRequestSerializer serializer]; sessionManager.requestSerializer.HTTPShouldHandleCookies = NO; sessionManager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments]; + NSMutableSet *acceptableContentTypes = sessionManager.responseSerializer.acceptableContentTypes.mutableCopy; + [acceptableContentTypes addObject:@"text/plain"]; + sessionManager.responseSerializer.acceptableContentTypes = acceptableContentTypes; return sessionManager; } From 217b28b0041168df6f51943b9b25eeb72b9b7073 Mon Sep 17 00:00:00 2001 From: gmbnt Date: Wed, 25 Mar 2020 15:52:34 +1100 Subject: [PATCH 02/10] Fix clipping --- Signal/src/Loki/View Controllers/DeviceLinksVC.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Signal/src/Loki/View Controllers/DeviceLinksVC.swift b/Signal/src/Loki/View Controllers/DeviceLinksVC.swift index fbfcaac83..4090eafa2 100644 --- a/Signal/src/Loki/View Controllers/DeviceLinksVC.swift +++ b/Signal/src/Loki/View Controllers/DeviceLinksVC.swift @@ -219,12 +219,12 @@ private extension DeviceLinksVC { stackView.axis = .vertical stackView.distribution = .equalCentering stackView.spacing = Values.verySmallSpacing - stackView.set(.height, to: 36) + stackView.set(.height, to: 44) contentView.addSubview(stackView) stackView.pin(.leading, to: .leading, of: contentView, withInset: Values.largeSpacing) - stackView.pin(.top, to: .top, of: contentView, withInset: Values.mediumSpacing) + stackView.pin(.top, to: .top, of: contentView, withInset: 12) contentView.pin(.trailing, to: .trailing, of: stackView, withInset: Values.largeSpacing) - contentView.pin(.bottom, to: .bottom, of: stackView, withInset: Values.mediumSpacing) + contentView.pin(.bottom, to: .bottom, of: stackView, withInset: 12) stackView.set(.width, to: UIScreen.main.bounds.width - 2 * Values.largeSpacing) } From dd94074930e518173ef575eeaaaa9e5cf4b5f353 Mon Sep 17 00:00:00 2001 From: gmbnt Date: Wed, 25 Mar 2020 15:52:51 +1100 Subject: [PATCH 03/10] Don't limit random snode pool size --- SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift index 29e2febbb..d7dfea637 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift @@ -37,10 +37,9 @@ public extension LokiAPI { let target = seedNodePool.randomElement()! let url = URL(string: "\(target)/json_rpc")! let request = TSRequest(url: url, method: "POST", parameters: [ - "method" : "get_n_service_nodes", + "method" : "get_service_nodes", "params" : [ "active_only" : true, - "limit" : maxRandomSnodePoolSize, "fields" : [ "public_ip" : true, "storage_port" : true, From f115c06e97639dfbad049896660b8e72eb9a2c3e Mon Sep 17 00:00:00 2001 From: gmbnt Date: Wed, 25 Mar 2020 15:54:31 +1100 Subject: [PATCH 04/10] Add comment --- SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift index d7dfea637..4c63a061b 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift @@ -89,6 +89,7 @@ public extension LokiAPI { } internal static func getFileServerProxy() -> Promise { + // All of this has to happen on DispatchQueue.global() due to the way OWSMessageManager works let (promise, seal) = Promise.pending() func getVersion(for snode: LokiAPITarget) -> Promise { let url = URL(string: "\(snode.address):\(snode.port)/get_stats/v1")! From 90933c7856245f48619fd83aaf024c14c75de7ac Mon Sep 17 00:00:00 2001 From: gmbnt Date: Thu, 26 Mar 2020 11:22:04 +1100 Subject: [PATCH 05/10] Debug --- .../src/Loki/API/LokiAPI+SwarmAPI.swift | 10 ++++++---- .../src/Loki/API/LokiPoller.swift | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift index 4c63a061b..c922fbceb 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift @@ -92,11 +92,11 @@ public extension LokiAPI { // All of this has to happen on DispatchQueue.global() due to the way OWSMessageManager works let (promise, seal) = Promise.pending() func getVersion(for snode: LokiAPITarget) -> Promise { - let url = URL(string: "\(snode.address):\(snode.port)/get_stats/v1")! - let request = TSRequest(url: url) if let version = snodeVersion[snode] { return Promise { $0.fulfill(version) } } else { + let url = URL(string: "\(snode.address):\(snode.port)/get_stats/v1")! + let request = TSRequest(url: url) return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map(on: DispatchQueue.global()) { intermediate in let rawResponse = intermediate.responseObject guard let json = rawResponse as? JSON, let version = json["version"] as? String else { throw LokiAPIError.missingSnodeVersion } @@ -105,8 +105,8 @@ public extension LokiAPI { } } } - getRandomSnode().done(on: DispatchQueue.global()) { snode in - getVersion(for: snode).then(on: DispatchQueue.global()) { version -> Promise in + getRandomSnode().then(on: DispatchQueue.global()) { snode -> Promise in + return getVersion(for: snode).then(on: DispatchQueue.global()) { version -> Promise in if version >= "2.0.2" { print("[Loki] Using file server proxy with version number \(version).") return Promise { $0.fulfill(snode) } @@ -117,6 +117,8 @@ public extension LokiAPI { }.recover(on: DispatchQueue.global()) { error in return getFileServerProxy() } + }.done(on: DispatchQueue.global()) { snode in + seal.fulfill(snode) }.catch(on: DispatchQueue.global()) { error in seal.reject(error) } diff --git a/SignalServiceKit/src/Loki/API/LokiPoller.swift b/SignalServiceKit/src/Loki/API/LokiPoller.swift index 4b18f1945..ab8505bdf 100644 --- a/SignalServiceKit/src/Loki/API/LokiPoller.swift +++ b/SignalServiceKit/src/Loki/API/LokiPoller.swift @@ -9,7 +9,6 @@ public final class LokiPoller : NSObject { private var usedSnodes = Set() // MARK: Settings - private static let pollInterval: TimeInterval = 1 private static let retryInterval: TimeInterval = 4 // MARK: Initialization @@ -24,7 +23,7 @@ public final class LokiPoller : NSObject { print("[Loki] Started polling.") hasStarted = true hasStopped = false - openConnections() + setUpPolling() } @objc public func stopIfNeeded() { @@ -36,7 +35,7 @@ public final class LokiPoller : NSObject { } // MARK: Private API - private func openConnections() { + private func setUpPolling() { guard !hasStopped else { return } LokiAPI.getSwarm(for: getUserHexEncodedPublicKey()).then { [weak self] _ -> Promise in guard let strongSelf = self else { return Promise { $0.fulfill(()) } } @@ -45,10 +44,10 @@ public final class LokiPoller : NSObject { strongSelf.pollNextSnode(seal: seal) return promise }.ensure { [weak self] in - guard let strongSelf = self else { return } + guard let strongSelf = self, !strongSelf.hasStopped else { return } Timer.scheduledTimer(withTimeInterval: LokiPoller.retryInterval, repeats: false) { _ in guard let strongSelf = self else { return } - strongSelf.openConnections() + strongSelf.setUpPolling() } } } @@ -62,7 +61,9 @@ public final class LokiPoller : NSObject { let nextSnode = unusedSnodes.randomElement()! usedSnodes.insert(nextSnode) print("[Loki] Polling \(nextSnode).") - poll(nextSnode, seal: seal).catch(on: LokiAPI.errorHandlingQueue) { [weak self] error in + poll(nextSnode, seal: seal).done(on: DispatchQueue.global()) { + seal.fulfill(()) + }.catch(on: LokiAPI.errorHandlingQueue) { [weak self] error in print("[Loki] Polling \(nextSnode) failed; dropping it and switching to next snode.") LokiAPI.dropIfNeeded(nextSnode, hexEncodedPublicKey: userHexEncodedPublicKey) self?.pollNextSnode(seal: seal) @@ -72,12 +73,12 @@ public final class LokiPoller : NSObject { } } - private func poll(_ target: LokiAPITarget, seal: Resolver) -> Promise { + private func poll(_ target: LokiAPITarget, seal longTermSeal: Resolver) -> Promise { return LokiAPI.getRawMessages(from: target, usingLongPolling: false).then(on: DispatchQueue.global()) { [weak self] rawResponse -> Promise in - guard let strongSelf = self, !strongSelf.hasStopped else { return Promise.value(()) } + guard let strongSelf = self, !strongSelf.hasStopped else { return Promise { $0.fulfill(()) } } let messages = LokiAPI.parseRawMessagesResponse(rawResponse, from: target) strongSelf.onMessagesReceived(messages) - return strongSelf.poll(target, seal: seal) + return strongSelf.poll(target, seal: longTermSeal) } } } From 14015e2e38a88fd2eaee48ad2f8bfc8d2310b50f Mon Sep 17 00:00:00 2001 From: gmbnt Date: Thu, 26 Mar 2020 11:23:53 +1100 Subject: [PATCH 06/10] Update build number --- Signal.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index cc01f7177..2713decda 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -4294,7 +4294,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 64; + CURRENT_PROJECT_VERSION = 65; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -4356,7 +4356,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 64; + CURRENT_PROJECT_VERSION = 65; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -4410,7 +4410,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 64; + CURRENT_PROJECT_VERSION = 65; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = SUQ8J2PCT7; @@ -4479,7 +4479,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 64; + CURRENT_PROJECT_VERSION = 65; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = SUQ8J2PCT7; @@ -4688,7 +4688,7 @@ CODE_SIGN_ENTITLEMENTS = Signal/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 64; + CURRENT_PROJECT_VERSION = 65; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -4755,7 +4755,7 @@ CODE_SIGN_ENTITLEMENTS = Signal/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 64; + CURRENT_PROJECT_VERSION = 65; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", From 96cb307e1a488a69530906a99fd7bc4237f31560 Mon Sep 17 00:00:00 2001 From: gmbnt Date: Fri, 27 Mar 2020 10:36:18 +1100 Subject: [PATCH 07/10] Fix log --- SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift index c922fbceb..69c8399e5 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift @@ -48,7 +48,7 @@ public extension LokiAPI { ] ] ]) - print("[Loki] Invoking get_n_service_nodes on \(target).") + print("[Loki] Invoking get_service_nodes on \(target).") return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map(on: DispatchQueue.global()) { intermediate in let rawResponse = intermediate.responseObject guard let json = rawResponse as? JSON, let intermediate = json["result"] as? JSON, let rawTargets = intermediate["service_node_states"] as? [JSON] else { throw LokiAPIError.randomSnodePoolUpdatingFailed } From 16a06f753550b9d9e0d00c9367928ad272882920 Mon Sep 17 00:00:00 2001 From: gmbnt Date: Fri, 27 Mar 2020 10:38:35 +1100 Subject: [PATCH 08/10] Update for Swift 5.2 --- SignalMessaging/contacts/SystemContactsFetcher.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SignalMessaging/contacts/SystemContactsFetcher.swift b/SignalMessaging/contacts/SystemContactsFetcher.swift index ef4d6d22d..fe1525402 100644 --- a/SignalMessaging/contacts/SystemContactsFetcher.swift +++ b/SignalMessaging/contacts/SystemContactsFetcher.swift @@ -352,7 +352,7 @@ public class SystemContactsFetcher: NSObject { guard let contacts = fetchedContacts else { owsFailDebug("contacts was unexpectedly not set.") - completion(nil) + return completion(nil) } Logger.info("fetched \(contacts.count) contacts.") From c74de9698c16d8b6d844e1e85cce4765f6718c6e Mon Sep 17 00:00:00 2001 From: gmbnt Date: Fri, 27 Mar 2020 10:49:53 +1100 Subject: [PATCH 09/10] Fix copy --- Signal/src/Loki/View Controllers/BaseVC.swift | 2 +- .../ConversationView/ConversationViewController.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Signal/src/Loki/View Controllers/BaseVC.swift b/Signal/src/Loki/View Controllers/BaseVC.swift index 19803f660..8bdf37ab0 100644 --- a/Signal/src/Loki/View Controllers/BaseVC.swift +++ b/Signal/src/Loki/View Controllers/BaseVC.swift @@ -15,7 +15,7 @@ class BaseVC : UIViewController { @objc private func handleUnexpectedDeviceLinkRequestReceivedNotification() { guard DeviceLinkingUtilities.shouldShowUnexpectedDeviceLinkRequestReceivedAlert else { return } DispatchQueue.main.async { - let alert = UIAlertController(title: "Device Link Request Received", message: "Open the device link screen by going to \"Settings\"> \"Devices\" > \"Link a Device\" to link your devices.", preferredStyle: .alert) + let alert = UIAlertController(title: "Device Link Request Received", message: "Open the device link screen by going to \"Settings\" > \"Devices\" > \"Link a Device\" to link your devices.", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) self.present(alert, animated: true, completion: nil) } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index bdb42f243..58405b600 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -5488,7 +5488,7 @@ typedef enum : NSUInteger { { if (!LKDeviceLinkingUtilities.shouldShowUnexpectedDeviceLinkRequestReceivedAlert) { return; } dispatch_async(dispatch_get_main_queue(), ^{ - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Device Link Request Received" message:@"Open the device link screen by going to \"Settings\"> \"Devices\" > \"Link a Device\" to link your devices." preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Device Link Request Received" message:@"Open the device link screen by going to \"Settings\" > \"Devices\" > \"Link a Device\" to link your devices." preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; [self presentViewController:alert animated:YES completion:nil]; }); From 452469d9981c4f336315e1ffc093b9ba57342511 Mon Sep 17 00:00:00 2001 From: gmbnt Date: Fri, 27 Mar 2020 11:52:42 +1100 Subject: [PATCH 10/10] Fix access modifier --- SignalServiceKit/src/Loki/API/LokiAPI.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index ea60e5440..d69c1abde 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -2,10 +2,12 @@ import PromiseKit @objc(LKAPI) public final class LokiAPI : NSObject { + private static let stateQueue = DispatchQueue(label: "stateQueue") + /// Only ever modified from the message processing queue (`OWSBatchMessageProcessor.processingQueue`). private static var syncMessageTimestamps: [String:Set] = [:] - public static var _lastDeviceLinkUpdate: [String:Date] = [:] + private static var _lastDeviceLinkUpdate: [String:Date] = [:] /// A mapping from hex encoded public key to date updated. public static var lastDeviceLinkUpdate: [String:Date] { get { stateQueue.sync { _lastDeviceLinkUpdate } } @@ -19,8 +21,6 @@ public final class LokiAPI : NSObject { set { stateQueue.sync { _userHexEncodedPublicKeyCache = newValue } } } - private static let stateQueue = DispatchQueue(label: "stateQueue") - /// All service node related errors must be handled on this queue to avoid race conditions maintaining e.g. failure counts. public static let errorHandlingQueue = DispatchQueue(label: "errorHandlingQueue")