This commit is contained in:
spaced4ndy
2026-05-29 17:02:55 +04:00
parent 0bf0b46fcb
commit b7ec5e616b
2 changed files with 12 additions and 5 deletions
+8 -1
View File
@@ -2961,7 +2961,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
_ -> pure (conn', Nothing)
xGrpMemNew :: GroupInfo -> GroupMember -> MemberInfo -> Maybe MsgScope -> RcvMessage -> UTCTime -> CM (Maybe DeliveryJobScope)
xGrpMemNew gInfo m memInfo@(MemberInfo memId memRole _ _ _) msgScope_ msg brokerTs = do
xGrpMemNew gInfo m memInfo@(MemberInfo memId memRole _ _ assertedKey_) msgScope_ msg brokerTs = do
let fromRelay = useRelays' gInfo && isRelay m
unless fromRelay $ checkHostRole m memRole
if sameMemberId memId (membership gInfo)
@@ -2973,6 +2973,13 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
-- never the role or key (those are owner-authoritative via the roster, and
-- XGrpMemNew is unsigned)
| fromRelay && isRosterRole (memberRole' unknownMember) -> do
-- a member's key is immutable per memberId and identical across relays; mismatch
-- is unambiguous relay misbehavior (role can legitimately differ across relays
-- under multi-relay skew, so we deliberately don't warn on role)
let assertedKey = (\(MemberKey k) -> k) <$> assertedKey_
-- TODO [relays] member: surface relay-key-mismatch as a dedicated event / chat item / relay state
when (assertedKey /= memberPubKey unknownMember) $
messageWarning $ "x.grp.mem.new: relay asserted key differs from roster-established key, keeping roster key, memberId=" <> safeDecodeUtf8 (strEncode memId)
updatedMember <- withStore $ \db -> updateRosterMemberAnnounced db vr user m unknownMember memInfo initialStatus
-- roster members can't be pending, so no members-require-attention update
gInfo' <- updatePublicGroupData user gInfo
+4 -4
View File
@@ -26,7 +26,7 @@ import Data.Int (Int64)
import Data.List (intercalate, isInfixOf)
import qualified Data.Map.Strict as M
import qualified Data.Text as T
import Simplex.Chat.Controller (ChatConfig (..), ChatHooks (..), defaultChatHooks)
import Simplex.Chat.Controller (ChatConfig (..), ChatHooks (..), ChatLogLevel (..), defaultChatHooks)
import Simplex.Chat.Library.Internal (uniqueMsgMentions, updatedMentionNames)
import Simplex.Chat.Markdown (parseMaybeMarkdownList)
import Simplex.Chat.Messages (CIMention (..), CIMentionMember (..), ChatItemId)
@@ -9698,7 +9698,7 @@ testChannelRelayCannotDowngradeRosterMember ps =
withNewTestChat ps "alice" aliceProfile $ \alice ->
withNewTestChatOpts ps relayTestOpts "bob" bobProfile $ \bob ->
withNewTestChat ps "cath" cathProfile $ \cath ->
withNewTestChat ps "frank" frankProfile $ \frank -> do
withNewTestChatOpts ps (testOpts {coreOptions = testCoreOpts {logLevel = CLLWarning}}) "frank" frankProfile $ \frank -> do
(shortLink, fullLink) <- prepareChannel1Relay "team" alice bob
memberJoinChannel "team" [bob] [alice] shortLink fullLink cath
memberJoinChannel "team" [bob] [alice] shortLink fullLink frank
@@ -9727,17 +9727,17 @@ testChannelRelayCannotDowngradeRosterMember ps =
concurrentlyN_
[ alice <# "#team cath> hello from cath [>>]",
do
frank <##. "warning: x.grp.mem.new: relay asserted key differs from roster-established key, keeping roster key, memberId="
frank <## "#team: unknown member cath updated to cath"
frank <## "#team: bob introduced cath (Catherine) in the channel"
frank <# "#team cath> hello from cath [>>]"
]
threadDelay 100000
-- with the fix, frank's row for cath retains the roster-established role and key
checkMemberRow frank "cath" (Just "moderator")
frankKey <- getMemberPubKey frank "cath"
frankKey `shouldBe` realKey
where
getMemberPubKey :: HasCallStack => TestCC -> T.Text -> IO (Maybe ByteString)
getMemberPubKey :: TestCC -> T.Text -> IO (Maybe ByteString)
getMemberPubKey cc name = do
rows <- withCCTransaction cc $ \db ->
DB.query db "SELECT member_pub_key FROM group_members WHERE local_display_name = ?" (Only name) :: IO [Only (Maybe ByteString)]