From b721794a51ea2a4412e137c3523acf760bbf6e86 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Mon, 8 Feb 2021 09:37:39 +1100 Subject: [PATCH] Fix closed group update handling from before it was created --- .../Database/Storage+ClosedGroups.swift | 14 ++++++++++++++ .../MessageReceiver+Handling.swift | 15 ++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/SessionMessagingKit/Database/Storage+ClosedGroups.swift b/SessionMessagingKit/Database/Storage+ClosedGroups.swift index cda71072d..8ec789b85 100644 --- a/SessionMessagingKit/Database/Storage+ClosedGroups.swift +++ b/SessionMessagingKit/Database/Storage+ClosedGroups.swift @@ -9,6 +9,8 @@ extension Storage { } private static let closedGroupPublicKeyCollection = "SNClosedGroupPublicKeyCollection" + + private static let closedGroupFormationTimestampCollection = "SNClosedGroupFormationTimestampCollection" public func getClosedGroupEncryptionKeyPairs(for groupPublicKey: String) -> [ECKeyPair] { let collection = Storage.getClosedGroupEncryptionKeyPairCollection(for: groupPublicKey) @@ -45,6 +47,18 @@ extension Storage { (transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: groupPublicKey, inCollection: Storage.closedGroupPublicKeyCollection) } + public func getClosedGroupFormationTimestamp(for groupPublicKey: String) -> UInt64? { + var result: UInt64? + Storage.read { transaction in + result = transaction.object(forKey: groupPublicKey, inCollection: Storage.closedGroupFormationTimestampCollection) as? UInt64 + } + return result + } + + public func setClosedGroupFormationTimestamp(to timestamp: UInt64, for groupPublicKey: String, using transaction: Any) { + (transaction as! YapDatabaseReadWriteTransaction).setObject(timestamp, forKey: groupPublicKey, inCollection: Storage.closedGroupFormationTimestampCollection) + } + // MARK: - Ratchets diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift index 7e8125810..cfbb6b3b6 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift @@ -150,7 +150,7 @@ extension MessageReceiver { for closedGroup in message.closedGroups { guard !allClosedGroupPublicKeys.contains(closedGroup.publicKey) else { continue } handleNewClosedGroup(groupPublicKey: closedGroup.publicKey, name: closedGroup.name, encryptionKeyPair: closedGroup.encryptionKeyPair, - members: [String](closedGroup.members), admins: [String](closedGroup.admins), using: transaction) + members: [String](closedGroup.members), admins: [String](closedGroup.admins), messageSentTimestamp: message.sentTimestamp!, using: transaction) } let allOpenGroups = Set(storage.getAllUserOpenGroups().keys) for openGroupURL in message.openGroups { @@ -262,10 +262,11 @@ extension MessageReceiver { let groupPublicKey = publicKeyAsData.toHexString() let members = membersAsData.map { $0.toHexString() } let admins = adminsAsData.map { $0.toHexString() } - handleNewClosedGroup(groupPublicKey: groupPublicKey, name: name, encryptionKeyPair: encryptionKeyPair, members: members, admins: admins, using: transaction) + handleNewClosedGroup(groupPublicKey: groupPublicKey, name: name, encryptionKeyPair: encryptionKeyPair, + members: members, admins: admins, messageSentTimestamp: message.sentTimestamp!, using: transaction) } - private static func handleNewClosedGroup(groupPublicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: [String], admins: [String], using transaction: Any) { + private static func handleNewClosedGroup(groupPublicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: [String], admins: [String], messageSentTimestamp: UInt64, using transaction: Any) { let transaction = transaction as! YapDatabaseReadWriteTransaction // Create the group let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey) @@ -282,6 +283,8 @@ extension MessageReceiver { Storage.shared.addClosedGroupPublicKey(groupPublicKey, using: transaction) // Store the key pair Storage.shared.addClosedGroupEncryptionKeyPair(encryptionKeyPair, for: groupPublicKey, using: transaction) + // Store the formation timestamp + Storage.shared.setClosedGroupFormationTimestamp(to: messageSentTimestamp, for: groupPublicKey, using: transaction) // Notify the PN server let _ = PushNotificationAPI.performOperation(.subscribe, for: groupPublicKey, publicKey: getUserHexEncodedPublicKey()) // Notify the user @@ -459,8 +462,10 @@ extension MessageReceiver { } let group = thread.groupModel // Check that the message isn't from before the group was created - guard Double(message.sentTimestamp!) > thread.creationDate.timeIntervalSince1970 * 1000 else { - return SNLog("Ignoring closed group update from before thread was created.") + if let formationTimestamp = Storage.shared.getClosedGroupFormationTimestamp(for: groupPublicKey) { + guard message.sentTimestamp! > formationTimestamp else { + return SNLog("Ignoring closed group update from before thread was created.") + } } // Check that the sender is a member of the group guard Set(group.groupMemberIds).contains(message.sender!) else {