From 19a214f65397470905230bff21c224dbaf9785a4 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Wed, 20 May 2020 11:12:51 +1000 Subject: [PATCH] Fix simultaneous session request bug --- .../xcshareddata/xcschemes/Signal.xcscheme | 3 +++ .../Loki/Database/OWSPrimaryStorage+Loki.swift | 15 ++++++++++++++- .../Closed Groups/ClosedGroupsProtocol.swift | 3 ++- .../Loki/Protocol/Meta/SessionMetaProtocol.swift | 1 - .../SessionManagementProtocol.swift | 6 ++++++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Signal.xcodeproj/xcshareddata/xcschemes/Signal.xcscheme b/Signal.xcodeproj/xcshareddata/xcschemes/Signal.xcscheme index 915c5088b..64a8ba432 100644 --- a/Signal.xcodeproj/xcshareddata/xcschemes/Signal.xcscheme +++ b/Signal.xcodeproj/xcshareddata/xcschemes/Signal.xcscheme @@ -126,6 +126,9 @@ + + diff --git a/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift b/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift index f7a937360..1336fcff3 100644 --- a/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift +++ b/SignalServiceKit/src/Loki/Database/OWSPrimaryStorage+Loki.swift @@ -1,6 +1,18 @@ public extension OWSPrimaryStorage { + // MARK: Session Requests + private static let sessionRequestTimestampCollection = "LokiSessionRequestTimestampCollection" + + public func setSessionRequestTimestamp(for publicKey: String, to timestamp: Date, in transaction: YapDatabaseReadWriteTransaction) { + transaction.setDate(timestamp, forKey: publicKey, inCollection: OWSPrimaryStorage.sessionRequestTimestampCollection) + } + + public func getSessionRequestTimestamp(for publicKey: String, in transaction: YapDatabaseReadTransaction) -> Date? { + transaction.date(forKey: publicKey, inCollection: OWSPrimaryStorage.sessionRequestTimestampCollection) + } + + // MARK: Multi Device private static var deviceLinkCache: Set = [] private func getDeviceLinkCollection(for masterHexEncodedPublicKey: String) -> String { @@ -62,7 +74,8 @@ public extension OWSPrimaryStorage { public func getMasterHexEncodedPublicKey(for slaveHexEncodedPublicKey: String, in transaction: YapDatabaseReadTransaction) -> String? { return getDeviceLink(for: slaveHexEncodedPublicKey, in: transaction)?.master.hexEncodedPublicKey } - + + // MARK: Open Groups public func getUserCount(for publicChat: LokiPublicChat, in transaction: YapDatabaseReadTransaction) -> Int? { return transaction.object(forKey: publicChat.id, inCollection: "LokiPublicChatUserCountCollection") as? Int } diff --git a/SignalServiceKit/src/Loki/Protocol/Closed Groups/ClosedGroupsProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Closed Groups/ClosedGroupsProtocol.swift index 62b915812..ec5a18a7f 100644 --- a/SignalServiceKit/src/Loki/Protocol/Closed Groups/ClosedGroupsProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Closed Groups/ClosedGroupsProtocol.swift @@ -41,9 +41,10 @@ public final class ClosedGroupsProtocol : NSObject { let thread = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction) thread.save(with: transaction) let sessionRequestMessage = SessionRequestMessage(thread: thread) + storage.setSessionRequestTimestamp(for: hexEncodedPublicKey, to: Date(), in: transaction) let messageSenderJobQueue = SSKEnvironment.shared.messageSenderJobQueue // This has to happen sync to ensure that session requests get sent before AFRs do (it's - // asssumed that the master device first syncs closed groups first and contacts after that). + // asssumed that the master device syncs closed groups first and contacts after that). messageSenderJobQueue.add(message: sessionRequestMessage, transaction: transaction) } } diff --git a/SignalServiceKit/src/Loki/Protocol/Meta/SessionMetaProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Meta/SessionMetaProtocol.swift index fd374342e..92e880947 100644 --- a/SignalServiceKit/src/Loki/Protocol/Meta/SessionMetaProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Meta/SessionMetaProtocol.swift @@ -55,7 +55,6 @@ public final class SessionMetaProtocol : NSObject { } // MARK: Note to Self - @objc(isThreadNoteToSelf:) public static func isThreadNoteToSelf(_ thread: TSThread) -> Bool { guard let thread = thread as? TSContactThread else { return false } diff --git a/SignalServiceKit/src/Loki/Protocol/Session Management/SessionManagementProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Session Management/SessionManagementProtocol.swift index 82a4a0318..d34af79aa 100644 --- a/SignalServiceKit/src/Loki/Protocol/Session Management/SessionManagementProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Session Management/SessionManagementProtocol.swift @@ -145,6 +145,7 @@ public final class SessionManagementProtocol : NSObject { storage.dbReadWriteConnection.readWrite { transaction in let thread = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction) let sessionRequestMessage = SessionRequestMessage(thread: thread) + storage.setSessionRequestTimestamp(for: hexEncodedPublicKey, to: Date(), in: transaction) let messageSenderJobQueue = SSKEnvironment.shared.messageSenderJobQueue messageSenderJobQueue.add(message: sessionRequestMessage, transaction: transaction) } @@ -192,6 +193,11 @@ public final class SessionManagementProtocol : NSObject { public static func handleSessionRequestMessage(_ dataMessage: SSKProtoDataMessage, wrappedIn envelope: SSKProtoEnvelope, using transaction: YapDatabaseReadWriteTransaction) { // The envelope source is set during UD decryption let hexEncodedPublicKey = envelope.source! + if let sentSessionRequestTimestamp = storage.getSessionRequestTimestamp(for: hexEncodedPublicKey, in: transaction), + envelope.timestamp < NSDate.ows_millisecondsSince1970(for: sentSessionRequestTimestamp) { + // We sent a session request after this one was sent + return + } var closedGroupMembers: Set = [] TSGroupThread.enumerateCollectionObjects(with: transaction) { object, _ in guard let group = object as? TSGroupThread, group.groupModel.groupType == .closedGroup,