From 1fa9f2271a59fefec7bfc5c3784154c34620b6d3 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Wed, 18 Dec 2024 16:45:46 +1100 Subject: [PATCH] Fixed an issue where new legacy groups would have invalid state --- .../MessageReceiver+ClosedGroups.swift | 42 ++++++++++++++----- .../MessageSender+ClosedGroups.swift | 37 ++++++++-------- 2 files changed, 52 insertions(+), 27 deletions(-) diff --git a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+ClosedGroups.swift b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+ClosedGroups.swift index 79750f55c..d5a00dc5c 100644 --- a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+ClosedGroups.swift +++ b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+ClosedGroups.swift @@ -142,6 +142,7 @@ extension MessageReceiver { // approved contact (to prevent spam via closed groups getting around message requests if users are // on old or modified clients) var hasApprovedAdmin: Bool = false + let receivedTimestamp: TimeInterval = (TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000) for adminId in admins { if let contact: Contact = try? Contact.fetchOne(db, id: adminId), contact.isApproved { @@ -155,6 +156,36 @@ extension MessageReceiver { // antoher device) guard hasApprovedAdmin || configTriggeringChange != nil else { return } + // Create the disappearing config + let disappearingConfig: DisappearingMessagesConfiguration = DisappearingMessagesConfiguration + .defaultWith(groupPublicKey) + .with( + isEnabled: (expirationTimer > 0), + durationSeconds: TimeInterval(expirationTimer), + type: (expirationTimer > 0 ? .disappearAfterSend : .unknown) + ) + + /// Update `libSession` first + /// + /// **Note:** This **MUST** happen before we call `SessionThread.upsert` as we won't add the group + /// if it already exists in `libSession` and upserting the thread results in an update to `libSession` to set + /// the `priority` + if configTriggeringChange == nil { + try? LibSession.add( + db, + groupPublicKey: groupPublicKey, + name: name, + joinedAt: (TimeInterval(formationTimestampMs) / 1000), + latestKeyPairPublicKey: Data(encryptionKeyPair.publicKey), + latestKeyPairSecretKey: Data(encryptionKeyPair.secretKey), + latestKeyPairReceivedTimestamp: receivedTimestamp, + disappearingConfig: disappearingConfig, + members: members.asSet(), + admins: admins.asSet(), + using: dependencies + ) + } + // Create the group let thread: SessionThread = try SessionThread.upsert( db, @@ -198,20 +229,11 @@ extension MessageReceiver { } // Update the DisappearingMessages config - var disappearingConfig = DisappearingMessagesConfiguration.defaultWith(thread.id) if (try? thread.disappearingMessagesConfiguration.fetchOne(db)) == nil { - let isEnabled: Bool = (expirationTimer > 0) - disappearingConfig = try disappearingConfig - .with( - isEnabled: isEnabled, - durationSeconds: TimeInterval(expirationTimer), - type: isEnabled ? .disappearAfterSend : .unknown - ) - .saved(db) + try disappearingConfig.upsert(db) } // Store the key pair if it doesn't already exist - let receivedTimestamp: TimeInterval = (TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000) let newKeyPair: ClosedGroupKeyPair = ClosedGroupKeyPair( threadId: groupPublicKey, publicKey: Data(encryptionKeyPair.publicKey), diff --git a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageSender+ClosedGroups.swift b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageSender+ClosedGroups.swift index 2d08ddc96..cf3c75b81 100644 --- a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageSender+ClosedGroups.swift +++ b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageSender+ClosedGroups.swift @@ -39,6 +39,25 @@ extension MessageSender { let adminsAsData: [Data] = admins.map { Data(hex: $0) } let formationTimestamp: TimeInterval = (TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000) + /// Update `libSession` first + /// + /// **Note:** This **MUST** happen before we call `SessionThread.upsert` as we won't add the group + /// if it already exists in `libSession` and upserting the thread results in an update to `libSession` to set + /// the `priority` + try LibSession.add( + db, + groupPublicKey: groupPublicKey, + name: name, + joinedAt: formationTimestamp, + latestKeyPairPublicKey: Data(encryptionKeyPair.publicKey), + latestKeyPairSecretKey: Data(encryptionKeyPair.secretKey), + latestKeyPairReceivedTimestamp: formationTimestamp, + disappearingConfig: DisappearingMessagesConfiguration.defaultWith(groupPublicKey), + members: members, + admins: admins, + using: dependencies + ) + // Create the relevant objects in the database let thread: SessionThread = try SessionThread.upsert( db, @@ -55,12 +74,11 @@ extension MessageSender { ).insert(db) // Store the key pair - let latestKeyPairReceivedTimestamp: TimeInterval = (TimeInterval(SnodeAPI.currentOffsetTimestampMs()) / 1000) try ClosedGroupKeyPair( threadId: groupPublicKey, publicKey: Data(encryptionKeyPair.publicKey), secretKey: Data(encryptionKeyPair.secretKey), - receivedTimestamp: latestKeyPairReceivedTimestamp + receivedTimestamp: formationTimestamp ).insert(db) // Create the member objects @@ -82,21 +100,6 @@ extension MessageSender { ).save(db) } - // Update libSession - try LibSession.add( - db, - groupPublicKey: groupPublicKey, - name: name, - joinedAt: formationTimestamp, - latestKeyPairPublicKey: Data(encryptionKeyPair.publicKey), - latestKeyPairSecretKey: Data(encryptionKeyPair.secretKey), - latestKeyPairReceivedTimestamp: latestKeyPairReceivedTimestamp, - disappearingConfig: DisappearingMessagesConfiguration.defaultWith(groupPublicKey), - members: members, - admins: admins, - using: dependencies - ) - let memberSendData: [MessageSender.PreparedSendData] = try members .map { memberId -> MessageSender.PreparedSendData in try MessageSender.preparedSendData(