This commit is contained in:
spaced4ndy
2026-05-28 12:03:23 +04:00
parent 0c3883fad8
commit 30698a36ff
3 changed files with 43 additions and 18 deletions
+1 -1
View File
@@ -144,7 +144,7 @@ getConnectionEntity db vr user@User {userId, userContactId} agentConnId = do
g.conn_full_link_to_connect, g.conn_short_link_to_connect, g.conn_link_prepared_connection, g.conn_link_started_connection, g.welcome_shared_msg_id, g.request_shared_msg_id,
g.business_chat, g.business_member_id, g.customer_member_id,
g.use_relays, g.relay_own_status,
g.ui_themes, g.summary_current_members_count, g.public_member_count, g.custom_data, g.chat_item_ttl, g.members_require_attention, g.via_group_link_uri,
g.ui_themes, g.summary_current_members_count, g.public_member_count, g.roster_version, g.custom_data, g.chat_item_ttl, g.members_require_attention, g.via_group_link_uri,
g.root_priv_key, g.root_pub_key, g.member_priv_key,
-- GroupInfo {membership}
mu.group_member_id, mu.group_id, mu.index_in_group, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
@@ -9,7 +9,7 @@ import Text.RawString.QQ (r)
m20260526_group_roster :: Text
m20260526_group_roster =
[r|
ALTER TABLE groups ADD COLUMN roster_version SMALLINT;
ALTER TABLE groups ADD COLUMN roster_version INTEGER;
ALTER TABLE groups ADD COLUMN roster_msg_body BYTEA;
ALTER TABLE groups ADD COLUMN roster_msg_chat_binding TEXT;
ALTER TABLE groups ADD COLUMN roster_msg_signatures BYTEA;
+41 -16
View File
@@ -269,6 +269,7 @@ chatGroupTests = do
it "should change member role (signed)" testChannelChangeRoleSigned
it "should block member for all (signed)" testChannelBlockMemberSigned
it "moderator action verifies via owner-signed roster" testChannelModeratorActionViaRoster
it "removed moderator drops from the roster cache" testChannelRemovedModeratorRefreshesRoster
it "should remove member (signed)" testChannelRemoveMemberSigned
it "should delete channel (signed)" testChannelDeleteGroupSigned
it "should delete channel and clean up relay connections" testChannelDeleteGroupCleanup
@@ -9514,31 +9515,55 @@ testChannelModeratorActionViaRoster ps =
eve <# "#team dan> hello from dan [>>]"
]
-- alice promotes cath to moderator. dan and eve don't know cath, so the
-- XGrpMemRole errors on them, but the owner-signed roster (broadcast on
-- the set change) silently gives them cath's key + name + moderator role.
-- alice promotes cath to moderator. dan and eve don't know cath yet, so
-- XGrpMemRole errors for them; the owner-signed roster (broadcast on the
-- set change) silently gives them cath's key, name and moderator role.
threadDelay 1000000
alice ##> "/mr #team cath moderator"
alice <## "#team: you changed the role of cath to moderator (signed)"
bob <## "#team: alice changed the role of cath from member to moderator (signed)"
concurrentlyN_
[ cath <## "#team: alice changed your role from member to moderator (signed)",
dan <## "error: x.grp.mem.role with unknown member ID",
eve <## "error: x.grp.mem.role with unknown member ID"
]
-- cath (moderator) blocks dan. cath's signed XGrpMemRestrict is forwarded
-- by the relay; eve verifies it against cath's roster-established key.
cath <## "#team: alice changed your role from member to moderator (signed)"
dan <##. "error: x.grp.mem.role"
eve <##. "error: x.grp.mem.role"
-- cath (moderator) blocks dan; eve verifies the signed block against the
-- roster-established key ("(signed)" => verified). cath's profile arrives
-- prepended to the forwarded block.
threadDelay 1000000
cath ##> "/block for all #team dan"
cath <## "#team: you blocked dan (signed)"
bob <## "#team: cath blocked dan (signed)"
-- eve learned cath (name, key, moderator role) only from the roster;
-- cath's profile arrives with the forwarded block, then the block
-- verifies against cath's roster key. "(signed)" => eve verified it.
eve <## "#team: unknown member cath updated to cath"
eve <## "#team: bob introduced cath (Catherine) in the channel"
alice <## "#team: cath blocked dan (signed)"
eve <##. "#team: unknown member cath"
eve <##. "#team: bob introduced cath"
eve <## "#team: cath blocked dan (signed)"
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 ->
withNewTestChatOpts ps relayTestOpts "bob" bobProfile $ \bob ->
withNewTestChat ps "cath" cathProfile $ \cath ->
withNewTestChat ps "dan" danProfile $ \dan ->
withNewTestChat ps "eve" eveProfile $ \eve -> do
createChannel1Relay "team" alice bob cath dan eve
threadDelay 1000000
alice ##> "/mr #team cath moderator"
alice <## "#team: you changed the role of cath to moderator (signed)"
bob <## "#team: alice changed the role of cath from member to moderator (signed)"
cath <## "#team: alice changed your role from member to moderator (signed)"
dan <##. "error: x.grp.mem.role"
eve <##. "error: x.grp.mem.role"
threadDelay 1000000
alice ##> "/rm #team cath"
alice <## "#team: you removed cath from the group (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"
dan .<##. ("#team: alice removed cath", "(signed)")
eve .<##. ("#team: alice removed cath", "(signed)")
testChannelRemoveMemberSigned :: HasCallStack => TestParams -> IO ()
testChannelRemoveMemberSigned ps =