Fix device verification UX: show request card, enable cross-user SAS

- RenderMessageContent: add case for m.key.verification.request msgtype
  so it renders an informational card instead of "Unsupported message"
- MsgTypeRenderers/FallbackContent: add VerificationRequestContent and
  MessageVerificationRequestContent components (lock icon + instructional text)
- DeviceVerification: remove isSelfVerification guard from
  ReceiveSelfDeviceVerification so cross-user verification requests also
  trigger the SAS emoji dialog (was silently dropped before)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 11:15:49 -04:00
parent 37e68e906b
commit 8740752aec
4 changed files with 23 additions and 4 deletions
@@ -316,9 +316,5 @@ export function ReceiveSelfDeviceVerification() {
if (!request) return null;
if (!request.isSelfVerification) {
return null;
}
return <DeviceVerification request={request} onExit={handleExit} />;
}
@@ -22,6 +22,7 @@ import {
RenderBody,
ThumbnailContent,
UnsupportedContent,
VerificationRequestContent,
VideoContent,
} from './message';
import { UrlPreviewCard, UrlPreviewHolder } from './url-preview';
@@ -264,5 +265,9 @@ export function RenderMessageContent({
return <MBadEncrypted />;
}
if (msgType === 'm.key.verification.request') {
return <VerificationRequestContent />;
}
return <UnsupportedContent />;
}
@@ -10,6 +10,7 @@ import {
MessageDeletedContent,
MessageEditedContent,
MessageUnsupportedContent,
MessageVerificationRequestContent,
} from './content';
import {
IAudioContent,
@@ -57,6 +58,14 @@ export function UnsupportedContent() {
);
}
export function VerificationRequestContent() {
return (
<Text>
<MessageVerificationRequestContent />
</Text>
);
}
export function BrokenContent() {
return (
<Text>
@@ -57,6 +57,15 @@ export const MessageEmptyContent = as<'div', { children?: never }>(({ ...props }
</Box>
));
export const MessageVerificationRequestContent = as<'div', { children?: never }>(
({ ...props }, ref) => (
<Box as="span" alignItems="Center" gap="100" style={warningStyle} {...props} ref={ref}>
<Icon size="50" src={Icons.Lock} />
<i>Device verification request open another Matrix client to accept</i>
</Box>
),
);
export const MessageEditedContent = as<'span', { children?: never }>(({ ...props }, ref) => (
<Text as="span" size="T200" priority="300" {...props} ref={ref}>
{' (edited)'}