From c862b0e30a730276da1ae5c868fc8cf93310c550 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Mon, 29 Jan 2024 10:31:28 +1100 Subject: [PATCH] Fixed an issue where group invite auto accept wasn't sending a response --- .../Database/Models/ClosedGroup.swift | 21 +++++- .../MessageReceiver+Groups.swift | 66 ++++++++++++------- 2 files changed, 61 insertions(+), 26 deletions(-) diff --git a/SessionMessagingKit/Database/Models/ClosedGroup.swift b/SessionMessagingKit/Database/Models/ClosedGroup.swift index ce84f71ca..63871dffb 100644 --- a/SessionMessagingKit/Database/Models/ClosedGroup.swift +++ b/SessionMessagingKit/Database/Models/ClosedGroup.swift @@ -181,12 +181,12 @@ public extension ClosedGroup { case userGroup } - static func approveGroup( + @discardableResult static func approveGroup( _ db: Database, group: ClosedGroup, calledFromConfigHandling: Bool, using dependencies: Dependencies - ) throws { + ) throws -> Job? { guard let userED25519KeyPair: KeyPair = Identity.fetchUserEd25519KeyPair(db, using: dependencies) else { throw MessageReceiverError.noUserED25519KeyPair } @@ -223,7 +223,20 @@ public extension ClosedGroup { ) } - /// Start polling + /// Schedule a `pollResponseJob` to be triggered once the first poll completes the start polling + let pollResponseJob: Job? = dependencies[singleton: .jobRunner].add( + db, + job: Job(variant: .manualResultJob), + canStartJob: true, + using: dependencies + ) + dependencies[singleton: .groupsPoller].afterNextPoll(for: group.id) { _ in + dependencies[singleton: .jobRunner].manuallyTriggerResult( + pollResponseJob, + result: .succeeded, + using: dependencies + ) + } dependencies[singleton: .groupsPoller].startIfNeeded(for: group.id, using: dependencies) /// Subscribe for group push notifications @@ -239,6 +252,8 @@ public extension ClosedGroup { .subscribe(on: DispatchQueue.global(qos: .userInitiated), using: dependencies) .sinkUntilComplete() } + + return pollResponseJob } static func removeData( diff --git a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Groups.swift b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Groups.swift index 7695f791a..f5b009ae3 100644 --- a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Groups.swift +++ b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Groups.swift @@ -134,8 +134,7 @@ extension MessageReceiver { groupSessionId: message.groupSessionId, using: dependencies ) - - try MessageReceiver.handleNewGroup( + let pollResponseJob: Job? = try MessageReceiver.handleNewGroup( db, groupSessionId: message.groupSessionId.hexString, groupIdentityPrivateKey: nil, @@ -190,26 +189,47 @@ extension MessageReceiver { ).inserted(db) /// Notify the user about the group message request if needed - guard !inviteSenderIsApproved else { return } - - let isMainAppActive: Bool = dependencies[defaults: .appGroup, key: .isMainAppActive] - dependencies[singleton: .notificationsManager].notifyUser( - db, - for: interaction, - in: try SessionThread.fetchOrCreate( - db, - id: message.groupSessionId.hexString, - variant: .group, - shouldBeVisible: nil, - calledFromConfigHandling: false, - using: dependencies - ), - applicationState: (isMainAppActive ? .active : .background), - using: dependencies - ) + switch inviteSenderIsApproved { + /// If the sender was approved then this group will be auto-accepted and we should send the + /// `GroupUpdateInviteResponseMessage` to the group + case true: + /// If we aren't creating a new thread (ie. sending a message request) then send a + /// `GroupUpdateInviteResponseMessage` to the group (this allows other members + /// to know that the user has joined the group) + try MessageSender.send( + db, + message: GroupUpdateInviteResponseMessage( + isApproved: true, + sentTimestamp: UInt64(SnodeAPI.currentOffsetTimestampMs(using: dependencies)) + ), + interactionId: nil, + threadId: message.groupSessionId.hexString, + threadVariant: .group, + after: pollResponseJob, + using: dependencies + ) + + /// If the sender wasn't approved this is a message request so we should notify the user about the invite + case false: + let isMainAppActive: Bool = dependencies[defaults: .appGroup, key: .isMainAppActive] + dependencies[singleton: .notificationsManager].notifyUser( + db, + for: interaction, + in: try SessionThread.fetchOrCreate( + db, + id: message.groupSessionId.hexString, + variant: .group, + shouldBeVisible: nil, + calledFromConfigHandling: false, + using: dependencies + ), + applicationState: (isMainAppActive ? .active : .background), + using: dependencies + ) + } } - internal static func handleNewGroup( + @discardableResult internal static func handleNewGroup( _ db: Database, groupSessionId: String, groupIdentityPrivateKey: Data?, @@ -219,7 +239,7 @@ extension MessageReceiver { invited: Bool, calledFromConfigHandling: Bool, using dependencies: Dependencies - ) throws { + ) throws -> Job? { // Create the group try SessionThread.fetchOrCreate( db, @@ -254,9 +274,9 @@ extension MessageReceiver { } // If the group is not in the invite state then handle the approval process - guard !invited else { return } + guard !invited else { return nil } - try ClosedGroup.approveGroup( + return try ClosedGroup.approveGroup( db, group: closedGroup, calledFromConfigHandling: calledFromConfigHandling,