From 50aca792786077edc8e0a0b73cfdc9263c7145d4 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Wed, 8 Jan 2025 15:29:39 +1100 Subject: [PATCH] Updated the group control messages to conform to the disappearing messages setting --- .../Jobs/GroupLeavingJob.swift | 7 ++- .../LibSession+UserGroups.swift | 4 ++ .../MessageReceiver+Groups.swift | 47 ++++++++++++++++++- .../MessageSender+Groups.swift | 41 ++++++++++++++-- .../Sending & Receiving/MessageReceiver.swift | 1 + 5 files changed, 93 insertions(+), 7 deletions(-) diff --git a/SessionMessagingKit/Jobs/GroupLeavingJob.swift b/SessionMessagingKit/Jobs/GroupLeavingJob.swift index f9afac54d..a6ffa1489 100644 --- a/SessionMessagingKit/Jobs/GroupLeavingJob.swift +++ b/SessionMessagingKit/Jobs/GroupLeavingJob.swift @@ -99,10 +99,14 @@ public enum GroupLeavingJob: JobExecutor { ) case (.group, .leave, _, false): + let disappearingConfig: DisappearingMessagesConfiguration? = try? DisappearingMessagesConfiguration.fetchOne(db, id: threadId) + return .leave( try SnodeAPI .preparedBatch( requests: [ + /// Don't expire the `GroupUpdateMemberLeftMessage` as that's not a UI-based + /// message (it's an instruction for admin devices) try MessageSender.preparedSend( db, message: GroupUpdateMemberLeftMessage(), @@ -114,7 +118,8 @@ public enum GroupLeavingJob: JobExecutor { ), try MessageSender.preparedSend( db, - message: GroupUpdateMemberLeftNotificationMessage(), + message: GroupUpdateMemberLeftNotificationMessage() + .with(disappearingConfig), to: destination, namespace: destination.defaultNamespace, interactionId: nil, diff --git a/SessionMessagingKit/LibSession/Config Handling/LibSession+UserGroups.swift b/SessionMessagingKit/LibSession/Config Handling/LibSession+UserGroups.swift index 8e6cc7bb1..353d6b72e 100644 --- a/SessionMessagingKit/LibSession/Config Handling/LibSession+UserGroups.swift +++ b/SessionMessagingKit/LibSession/Config Handling/LibSession+UserGroups.swift @@ -452,6 +452,10 @@ internal extension LibSessionCacheType { (group.authData != nil || group.groupIdentityPrivateKey != nil) && (existingGroups[group.groupSessionId] == nil || group.wasKickedFromGroup == true) { + /// **Note:** In `MessageReceiver+Groups` we don't apply the disappearing message config settings to the + /// invitation control message because we wouldn't have them at that point - technically we might have them here + /// since the user was already part of the group, but they _may_ be stale so it'd be better to just behave consistently + /// and not disappear like the original one _ = try Interaction( threadId: group.groupSessionId, threadVariant: .group, diff --git a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Groups.swift b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Groups.swift index 52d403033..7d56d19b6 100644 --- a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Groups.swift +++ b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Groups.swift @@ -12,6 +12,7 @@ extension MessageReceiver { threadId: String, threadVariant: SessionThread.Variant, message: Message, + serverExpirationTimestamp: TimeInterval?, using dependencies: Dependencies ) throws { switch (message, try? SessionId(from: threadId)) { @@ -34,6 +35,7 @@ extension MessageReceiver { db, groupSessionId: sessionId, message: message, + serverExpirationTimestamp: serverExpirationTimestamp, using: dependencies ) @@ -42,6 +44,7 @@ extension MessageReceiver { db, groupSessionId: sessionId, message: message, + serverExpirationTimestamp: serverExpirationTimestamp, using: dependencies ) @@ -58,6 +61,7 @@ extension MessageReceiver { db, groupSessionId: sessionId, message: message, + serverExpirationTimestamp: serverExpirationTimestamp, using: dependencies ) @@ -315,6 +319,7 @@ extension MessageReceiver { _ db: Database, groupSessionId: SessionId, message: GroupUpdateInfoChangeMessage, + serverExpirationTimestamp: TimeInterval?, using dependencies: Dependencies ) throws { guard @@ -333,6 +338,15 @@ extension MessageReceiver { // Add a record of the specific change to the conversation (the actual change is handled via // config messages so these are only for record purposes) + let messageExpirationInfo: Message.MessageExpirationInfo = Message.getMessageExpirationInfo( + threadVariant: .group, + wasRead: false, // Only relevant for `DaR` messages which aren't supported in groups + serverExpirationTimestamp: serverExpirationTimestamp, + expiresInSeconds: message.expiresInSeconds, + expiresStartedAtMs: message.expiresStartedAtMs, + using: dependencies + ) + switch message.changeType { case .name: _ = try Interaction( @@ -346,6 +360,8 @@ extension MessageReceiver { .defaulting(to: ClosedGroup.MessageInfo.updatedNameFallback) .infoString(using: dependencies), timestampMs: Int64(sentTimestampMs), + expiresInSeconds: messageExpirationInfo.expiresInSeconds, + expiresStartedAtMs: messageExpirationInfo.expiresStartedAtMs, using: dependencies ).inserted(db) @@ -360,6 +376,8 @@ extension MessageReceiver { .updatedDisplayPicture .infoString(using: dependencies), timestampMs: Int64(sentTimestampMs), + expiresInSeconds: messageExpirationInfo.expiresInSeconds, + expiresStartedAtMs: messageExpirationInfo.expiresStartedAtMs, using: dependencies ).inserted(db) @@ -379,7 +397,7 @@ extension MessageReceiver { authorId: sender, timestampMs: Int64(sentTimestampMs), serverHash: message.serverHash, - serverExpirationTimestamp: nil, + serverExpirationTimestamp: serverExpirationTimestamp, using: dependencies ) } @@ -389,6 +407,7 @@ extension MessageReceiver { _ db: Database, groupSessionId: SessionId, message: GroupUpdateMemberChangeMessage, + serverExpirationTimestamp: TimeInterval?, using dependencies: Dependencies ) throws { guard @@ -456,6 +475,15 @@ extension MessageReceiver { switch messageInfo.infoString(using: dependencies) { case .none: Log.warn(.messageReceiver, "Failed to encode member change info string.") case .some(let messageBody): + let messageExpirationInfo: Message.MessageExpirationInfo = Message.getMessageExpirationInfo( + threadVariant: .group, + wasRead: false, // Only relevant for `DaR` messages which aren't supported in groups + serverExpirationTimestamp: serverExpirationTimestamp, + expiresInSeconds: message.expiresInSeconds, + expiresStartedAtMs: message.expiresStartedAtMs, + using: dependencies + ) + _ = try Interaction( threadId: groupSessionId.hexString, threadVariant: .group, @@ -463,6 +491,8 @@ extension MessageReceiver { variant: .infoGroupMembersUpdated, body: messageBody, timestampMs: Int64(sentTimestampMs), + expiresInSeconds: messageExpirationInfo.expiresInSeconds, + expiresStartedAtMs: messageExpirationInfo.expiresStartedAtMs, using: dependencies ).inserted(db) } @@ -502,6 +532,7 @@ extension MessageReceiver { _ db: Database, groupSessionId: SessionId, message: GroupUpdateMemberLeftNotificationMessage, + serverExpirationTimestamp: TimeInterval?, using dependencies: Dependencies ) throws { guard @@ -511,6 +542,15 @@ extension MessageReceiver { // Add a record of the specific change to the conversation (the actual change is handled via // config messages so these are only for record purposes) + let messageExpirationInfo: Message.MessageExpirationInfo = Message.getMessageExpirationInfo( + threadVariant: .group, + wasRead: false, // Only relevant for `DaR` messages which aren't supported in groups + serverExpirationTimestamp: serverExpirationTimestamp, + expiresInSeconds: message.expiresInSeconds, + expiresStartedAtMs: message.expiresStartedAtMs, + using: dependencies + ) + _ = try Interaction( threadId: groupSessionId.hexString, threadVariant: .group, @@ -526,6 +566,8 @@ extension MessageReceiver { ) .infoString(using: dependencies), timestampMs: Int64(sentTimestampMs), + expiresInSeconds: messageExpirationInfo.expiresInSeconds, + expiresStartedAtMs: messageExpirationInfo.expiresStartedAtMs, using: dependencies ).inserted(db) } @@ -898,6 +940,9 @@ extension MessageReceiver { .filter(Interaction.Columns.variant == Interaction.Variant.infoGroupInfoInvited) .deleteAll(db) + /// Unline most control messages we don't bother setting expiration values for this message, this is because we won't actually + /// have the current disappearing messages config as we won't have polled the group yet (and the settings are stored in the + /// `GroupInfo` config) let interaction: Interaction = try Interaction( threadId: groupSessionId.hexString, threadVariant: .group, diff --git a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageSender+Groups.swift b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageSender+Groups.swift index 13585cda5..08a0045cf 100644 --- a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageSender+Groups.swift +++ b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageSender+Groups.swift @@ -299,6 +299,8 @@ extension MessageSender { // Add a record of the name change to the conversation if name != closedGroup.name { + let disappearingConfig: DisappearingMessagesConfiguration? = try? DisappearingMessagesConfiguration.fetchOne(db, id: sessionId.hexString) + _ = try Interaction( threadId: groupSessionId, threadVariant: .group, @@ -308,6 +310,10 @@ extension MessageSender { .updatedName(name) .infoString(using: dependencies), timestampMs: changeTimestampMs, + expiresInSeconds: disappearingConfig?.expiresInSeconds(), + expiresStartedAtMs: disappearingConfig?.initialExpiresStartedAtMs( + sentTimestampMs: Double(changeTimestampMs) + ), using: dependencies ).inserted(db) @@ -324,7 +330,7 @@ extension MessageSender { using: dependencies ), using: dependencies - ), + ).with(disappearingConfig), interactionId: nil, threadId: sessionId.hexString, threadVariant: .group, @@ -379,6 +385,8 @@ extension MessageSender { default: throw MessageSenderError.invalidClosedGroupUpdate } + let disappearingConfig: DisappearingMessagesConfiguration? = try? DisappearingMessagesConfiguration.fetchOne(db, id: sessionId.hexString) + // Add a record of the change to the conversation _ = try Interaction( threadId: groupSessionId, @@ -389,6 +397,10 @@ extension MessageSender { .updatedDisplayPicture .infoString(using: dependencies), timestampMs: changeTimestampMs, + expiresInSeconds: disappearingConfig?.expiresInSeconds(), + expiresStartedAtMs: disappearingConfig?.initialExpiresStartedAtMs( + sentTimestampMs: Double(changeTimestampMs) + ), using: dependencies ).inserted(db) @@ -404,7 +416,7 @@ extension MessageSender { using: dependencies ), using: dependencies - ), + ).with(disappearingConfig), interactionId: nil, threadId: sessionId.hexString, threadVariant: .group, @@ -567,7 +579,7 @@ extension MessageSender { ed25519SecretKey: Array(groupIdentityPrivateKey) ), using: dependencies - ), + ).with(try? DisappearingMessagesConfiguration.fetchOne(db, id: sessionId.hexString)), to: .closedGroup(groupPublicKey: sessionId.hexString), namespace: .groupMessages, interactionId: nil, @@ -594,6 +606,8 @@ extension MessageSender { let userSessionId: SessionId = dependencies[cache: .general].sessionId dependencies[singleton: .storage].writeAsync { db in + let disappearingConfig: DisappearingMessagesConfiguration? = try? DisappearingMessagesConfiguration.fetchOne(db, id: sessionId.hexString) + /// Add a record of the change to the conversation _ = try? Interaction( threadId: groupSessionId, @@ -613,6 +627,10 @@ extension MessageSender { ) .infoString(using: dependencies), timestampMs: changeTimestampMs, + expiresInSeconds: disappearingConfig?.expiresInSeconds(), + expiresStartedAtMs: disappearingConfig?.initialExpiresStartedAtMs( + sentTimestampMs: Double(changeTimestampMs) + ), using: dependencies ).inserted(db) @@ -798,6 +816,7 @@ extension MessageSender { .fetchAll(db)) .defaulting(to: []) .reduce(into: [:]) { result, next in result[next.id] = next } + let disappearingConfig: DisappearingMessagesConfiguration? = try? DisappearingMessagesConfiguration.fetchOne(db, id: sessionId.hexString) /// Add a record of the change to the conversation _ = try Interaction( @@ -817,6 +836,10 @@ extension MessageSender { ) .infoString(using: dependencies), timestampMs: targetChangeTimestampMs, + expiresInSeconds: disappearingConfig?.expiresInSeconds(), + expiresStartedAtMs: disappearingConfig?.initialExpiresStartedAtMs( + sentTimestampMs: Double(targetChangeTimestampMs) + ), using: dependencies ).inserted(db) @@ -833,7 +856,7 @@ extension MessageSender { ed25519SecretKey: Array(groupIdentityPrivateKey) ), using: dependencies - ), + ).with(disappearingConfig), interactionId: nil, threadId: sessionId.hexString, threadVariant: .group, @@ -918,6 +941,8 @@ extension MessageSender { var memberChangeRequest: Network.PreparedRequest? if sendAdminChangedMessage && !membersReceivingPromotions.isEmpty { + let disappearingConfig: DisappearingMessagesConfiguration? = try? DisappearingMessagesConfiguration.fetchOne(db, id: groupSessionId.hexString) + memberChangeRequest = try MessageSender.preparedSend( db, message: GroupUpdateMemberChangeMessage( @@ -931,7 +956,7 @@ extension MessageSender { using: dependencies ), using: dependencies - ), + ).with(disappearingConfig), to: .closedGroup(groupPublicKey: groupSessionId.hexString), namespace: .groupMessages, interactionId: nil, @@ -959,6 +984,8 @@ extension MessageSender { dependencies[singleton: .storage].writeAsync { db in if sendAdminChangedMessage && !membersReceivingPromotions.isEmpty { + let disappearingConfig: DisappearingMessagesConfiguration? = try? DisappearingMessagesConfiguration.fetchOne(db, id: groupSessionId.hexString) + _ = try Interaction( threadId: groupSessionId.hexString, threadVariant: .group, @@ -976,6 +1003,10 @@ extension MessageSender { ) .infoString(using: dependencies), timestampMs: changeTimestampMs, + expiresInSeconds: disappearingConfig?.expiresInSeconds(), + expiresStartedAtMs: disappearingConfig?.initialExpiresStartedAtMs( + sentTimestampMs: Double(changeTimestampMs) + ), using: dependencies ).inserted(db) } diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift index 3b2516e9a..e64fcd186 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift @@ -373,6 +373,7 @@ public enum MessageReceiver { threadId: threadId, threadVariant: threadVariant, message: message, + serverExpirationTimestamp: serverExpirationTimestamp, using: dependencies )