diff --git a/src/Simplex/Chat/Library/Subscriber.hs b/src/Simplex/Chat/Library/Subscriber.hs index c964df2b3d..883f6c985b 100644 --- a/src/Simplex/Chat/Library/Subscriber.hs +++ b/src/Simplex/Chat/Library/Subscriber.hs @@ -3442,18 +3442,22 @@ processAgentMessageConn cxt user@User {userId} corrId agentConnId agentMessage = `catchAllErrors` \_ -> pure (cs, as) emitRosterResults :: GroupInfo -> GroupMember -> UTCTime -> ([MemberId], [(GroupMember, GroupMemberRole, Bool)]) -> CM () - emitRosterResults gInfo author rosterBrokerTs (conflicts, applied) = do + emitRosterResults gInfo@GroupInfo {membership} author rosterBrokerTs (conflicts, applied) = do forM_ conflicts $ \mid' -> messageWarning $ "x.grp.roster: member key conflict, keeping trusted key, memberId=" <> safeDecodeUtf8 (strEncode mid') forM_ applied $ \(member, fromRole, created) -> - unless created $ createItems member fromRole + unless created $ emitRoleChange member fromRole where - createItems member fromRole = do + emitRoleChange member fromRole = do let toRole = memberRole' member - gEvent = RGEMemberRole (groupMemberId' member) (fromLocalProfile $ memberProfile member) toRole - (gInfo', author', scopeInfo) <- mkGroupChatScope gInfo author - ci <- createChatItem user (CDGroupRcv gInfo' scopeInfo author') False (CIRcvGroupEvent gEvent) Nothing (Just MSSVerified) (Just rosterBrokerTs) - toView $ CEvtNewChatItems user [ci] + (gInfo', author') <- + if sameMemberId (memberId' membership) member + then do + (gInfo', author', scopeInfo) <- mkGroupChatScope gInfo author + ci <- createChatItem user (CDGroupRcv gInfo' scopeInfo author') False (CIRcvGroupEvent $ RGEUserRole toRole) Nothing (Just MSSVerified) (Just rosterBrokerTs) + toView $ CEvtNewChatItems user [ci] + pure (gInfo', author') + else pure (gInfo, author) toView CEvtMemberRole {user, groupInfo = gInfo', byMember = author', member, fromRole, toRole, msgSigned = Just MSSVerified} sendRosterAck :: GroupInfo -> GroupMember -> VersionRoster -> Maybe Text -> CM () diff --git a/tests/ChatTests/Groups.hs b/tests/ChatTests/Groups.hs index 51fe8c54aa..25bde00104 100644 --- a/tests/ChatTests/Groups.hs +++ b/tests/ChatTests/Groups.hs @@ -9804,6 +9804,8 @@ testChannelRemovedModeratorRefreshesRoster ps = threadDelay 1000000 alice ##> "/rm #team cath" alice <## "#team: you removed cath from the group (signed)" + -- the relay applies the removal via the roster (revert to observer) before the delete delta + bob <## "#team: alice changed the role of cath from moderator to observer (signed)" bob <## "#team: alice removed cath from the group (signed)" cath <## "#team: alice removed you from the group (signed)" cath <## "use /d #team to delete the group" @@ -10024,6 +10026,8 @@ testChannelRemoveMemberSigned ps = threadDelay 1000000 alice ##> "/rm #team eve" alice <## "#team: you removed eve from the group (signed)" + -- the relay applies the removal via the roster (revert to observer) before the delete delta + bob <## "#team: alice changed the role of eve from member to observer (signed)" bob <## "#team: alice removed eve from the group (signed)" concurrentlyN_ [ cath <## "#team: alice removed eve from the group (signed)",