This commit is contained in:
spaced4ndy committed 2026-05-28 14:37:53 +04:00
1 parent f24a429587
commit ca7ddc7278
4 files changed
+15 -11

No files matched your search

+2 -2
View File
@@ -2143,7 +2143,7 @@ bumpAndBroadcastRoster user gInfo
let rosterVer = maybe 0 (+ 1) (rosterVersion gInfo)
(relays, roster) <- withStore' $ \db -> do
relays <- getGroupRelayMembers db vr user gInfo
mods <- getGroupModerators db vr user gInfo
mods <- getGroupModsNoOwners db vr user gInfo
setGroupRosterVersion db gInfo rosterVer
pure (relays, buildGroupRoster rosterVer mods)
forM_ (L.nonEmpty relays) $ \relays' ->
@@ -2154,7 +2154,7 @@ sendGroupRosterToRelay :: User -> GroupInfo -> GroupMember -> CM ()
sendGroupRosterToRelay user gInfo relayMember =
forM_ (rosterVersion gInfo) $ \rosterVer -> do
vr <- chatVersionRange
mods <- withStore' $ \db -> getGroupModerators db vr user gInfo
mods <- withStore' $ \db -> getGroupModsNoOwners db vr user gInfo
void $ sendGroupMessage' user gInfo [relayMember] (XGrpRoster (buildGroupRoster rosterVer mods))
sendGroupMessages :: MsgEncodingI e => User -> GroupInfo -> Maybe GroupChatScope -> ShowGroupAsSender -> [GroupMember] -> NonEmpty (ChatMsgEvent e) -> CM (NonEmpty (Either ChatError SndMessage), GroupSndResult)
+2 -2
View File
@@ -3176,9 +3176,9 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
warnings <- withStore' $ \db -> do
warnings <- forM entries (applyRosterEntryDB db)
-- absent privileged members revert to the joiner default
currentPriv <- getGroupModerators db vr user gInfo
currentPriv <- getGroupModsNoOwners db vr user gInfo
forM_ currentPriv $ \m ->
when (isRosterRole (memberRole' m) && memberId' m `notElem` rosterIds) $
when (memberId' m `notElem` rosterIds) $
updateGroupMemberRole db user m defaultRole
pure warnings
sequence_ warnings
+11
View File
@@ -67,6 +67,7 @@ module Simplex.Chat.Store.Groups
getGroupMembersByIndexes,
getSupportScopeMembersByIndexes,
getGroupModerators,
getGroupModsNoOwners,
getGroupRelayMembers,
getGroupMembersForExpiration,
getRemovedMembersToCleanup,
@@ -1204,6 +1205,16 @@ getGroupModerators db vr user@User {userId, userContactId} GroupInfo {groupId} =
(groupMemberQuery <> " WHERE m.user_id = ? AND m.group_id = ? AND (m.contact_id IS NULL OR m.contact_id != ?) AND m.member_role IN (?,?,?)")
(userId, groupId, userContactId, GRModerator, GRAdmin, GROwner)
-- Moderators and admins only, excluding owners. Use for roster-related paths
-- where owners must not be touched (owners are link-anchored, not roster-managed).
getGroupModsNoOwners :: DB.Connection -> VersionRangeChat -> User -> GroupInfo -> IO [GroupMember]
getGroupModsNoOwners db vr user@User {userId, userContactId} GroupInfo {groupId} = do
map (toContactMember vr user)
<$> DB.query
db
(groupMemberQuery <> " WHERE m.user_id = ? AND m.group_id = ? AND (m.contact_id IS NULL OR m.contact_id != ?) AND m.member_role IN (?,?)")
(userId, groupId, userContactId, GRModerator, GRAdmin)
getGroupRelayMembers :: DB.Connection -> VersionRangeChat -> User -> GroupInfo -> IO [GroupMember]
getGroupRelayMembers db vr user@User {userId, userContactId} GroupInfo {groupId} = do
map (toContactMember vr user)
-7
View File
@@ -9487,11 +9487,6 @@ testChannelBlockMemberSigned ps =
r2 `shouldStartWith` "blocked"
r2 `shouldEndWith` "(signed)"
-- End-to-end validation of the owner-signed roster: a member promoted to
-- moderator performs a SIGNED administrative action (block), and another member
-- who learned that moderator's key, name, and role ONLY from the roster (never
-- from a relay-asserted introduction) verifies and honors it. Without the
-- roster, eve would have no trusted key for cath and would reject the block.
testChannelModeratorActionViaRoster :: HasCallStack => TestParams -> IO ()
testChannelModeratorActionViaRoster ps =
withNewTestChat ps "alice" aliceProfile $ \alice ->
@@ -9539,8 +9534,6 @@ testChannelModeratorActionViaRoster ps =
dan <##. "#team: unknown member cath"
dan <##. "#team: bob introduced cath"
-- Removing a moderator triggers anyPrivilegedRemoved → bumpAndBroadcastRoster on the
-- owner, which refreshes the relay's cached roster (the broadcast is silent on members).
testChannelRemovedModeratorRefreshesRoster :: HasCallStack => TestParams -> IO ()
testChannelRemovedModeratorRefreshesRoster ps =
withNewTestChat ps "alice" aliceProfile $ \alice ->