From d1e6bb5b52983ca3c9e372eb71703df5fea6c8c8 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 29 Jun 2026 16:49:03 +0100 Subject: [PATCH] Add "user identity" display to dev tools (#33977) * Add "user identity" display to dev tools * Correct incorect hard-coded string in test mock * Fix up tests --- .../components/views/dialogs/devtools/Users.tsx | 17 +++++++++++++++++ apps/web/src/i18n/strings/en_EN.json | 2 ++ apps/web/test/test-utils/test-utils.ts | 1 + .../devtools/__snapshots__/Users-test.tsx.snap | 8 ++++++++ 4 files changed, 28 insertions(+) diff --git a/apps/web/src/components/views/dialogs/devtools/Users.tsx b/apps/web/src/components/views/dialogs/devtools/Users.tsx index aab47e672b..bcd54a612f 100644 --- a/apps/web/src/components/views/dialogs/devtools/Users.tsx +++ b/apps/web/src/components/views/dialogs/devtools/Users.tsx @@ -21,6 +21,8 @@ import { useAsyncMemo } from "../../../../hooks/useAsyncMemo"; import CopyableText from "../../elements/CopyableText"; import E2EIcon from "../../rooms/E2EIcon"; import { E2EStatus } from "../../../../utils/ShieldUtils"; +import SyntaxHighlight from "../../elements/SyntaxHighlight.tsx"; +import { stringify } from "./Event.tsx"; /** * Replacement function for `` tags in translation strings. @@ -164,6 +166,17 @@ const UserView: React.FC = ({ member, onBack }) => { [context, member], new Map(), ); + + const userIdentity = useAsyncMemo( + async () => { + const identity = await crypto?.getUserCrossSigningKeys(member.userId); + if (!identity) return null; + return {stringify(identity)}; + }, + [context, member], + null, + ); + // The device to show, if any. const [device, setDevice] = useState(null); @@ -209,6 +222,10 @@ const UserView: React.FC = ({ member, onBack }) => { ))} +
+

{_t("devtools|user_identity")}

+ {userIdentity ?? {_t("devtools|user_identity_unknown")}} +
); }; diff --git a/apps/web/src/i18n/strings/en_EN.json b/apps/web/src/i18n/strings/en_EN.json index c6f1563967..604aded410 100644 --- a/apps/web/src/i18n/strings/en_EN.json +++ b/apps/web/src/i18n/strings/en_EN.json @@ -904,6 +904,8 @@ "user_avatar": "Avatar: %(avatar)s", "user_displayname": "Displayname: %(displayname)s", "user_id": "User ID: %(userId)s", + "user_identity": "Cryptographic identity", + "user_identity_unknown": "Unknown", "user_no_avatar": "Avatar: None", "user_no_displayname": "Displayname: None", "user_read_up_to": "User read up to: ", diff --git a/apps/web/test/test-utils/test-utils.ts b/apps/web/test/test-utils/test-utils.ts index eb0532bbd9..9223c2413e 100644 --- a/apps/web/test/test-utils/test-utils.ts +++ b/apps/web/test/test-utils/test-utils.ts @@ -125,6 +125,7 @@ export function createTestClient(): MatrixClient { getOwnDeviceKeys: vi.fn().mockResolvedValue({ ed25519: "ed25519", curve25519: "curve25519" }), getUserDeviceInfo: vi.fn().mockResolvedValue(new Map()), getUserVerificationStatus: vi.fn(), + getUserCrossSigningKeys: vi.fn().mockResolvedValue(null), getDeviceVerificationStatus: vi.fn(), resetKeyBackup: vi.fn(), isEncryptionEnabledInRoom: vi.fn().mockResolvedValue(false), diff --git a/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/Users-test.tsx.snap b/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/Users-test.tsx.snap index ce61e31540..622df9d442 100644 --- a/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/Users-test.tsx.snap +++ b/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/Users-test.tsx.snap @@ -654,6 +654,14 @@ exports[` should render a single user 1`] = ` +
+

+ Cryptographic identity +

+ + Unknown + +