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
This commit is contained in:
Richard van der Hoff
2026-06-29 15:49:03 +00:00
committed by GitHub
parent c47b099025
commit d1e6bb5b52
4 changed files with 28 additions and 0 deletions
@@ -21,6 +21,8 @@ import { useAsyncMemo } from "../../../../hooks/useAsyncMemo";
import CopyableText from "../../elements/CopyableText"; import CopyableText from "../../elements/CopyableText";
import E2EIcon from "../../rooms/E2EIcon"; import E2EIcon from "../../rooms/E2EIcon";
import { E2EStatus } from "../../../../utils/ShieldUtils"; import { E2EStatus } from "../../../../utils/ShieldUtils";
import SyntaxHighlight from "../../elements/SyntaxHighlight.tsx";
import { stringify } from "./Event.tsx";
/** /**
* Replacement function for `<i>` tags in translation strings. * Replacement function for `<i>` tags in translation strings.
@@ -164,6 +166,17 @@ const UserView: React.FC<UserProps> = ({ member, onBack }) => {
[context, member], [context, member],
new Map(), new Map(),
); );
const userIdentity = useAsyncMemo(
async () => {
const identity = await crypto?.getUserCrossSigningKeys(member.userId);
if (!identity) return null;
return <SyntaxHighlight language="json">{stringify(identity)}</SyntaxHighlight>;
},
[context, member],
null,
);
// The device to show, if any. // The device to show, if any.
const [device, setDevice] = useState<Device | null>(null); const [device, setDevice] = useState<Device | null>(null);
@@ -209,6 +222,10 @@ const UserView: React.FC<UserProps> = ({ member, onBack }) => {
))} ))}
</ul> </ul>
</section> </section>
<section>
<h2>{_t("devtools|user_identity")}</h2>
{userIdentity ?? <i>{_t("devtools|user_identity_unknown")}</i>}
</section>
</BaseTool> </BaseTool>
); );
}; };
+2
View File
@@ -904,6 +904,8 @@
"user_avatar": "Avatar: %(avatar)s", "user_avatar": "Avatar: %(avatar)s",
"user_displayname": "Displayname: %(displayname)s", "user_displayname": "Displayname: %(displayname)s",
"user_id": "User ID: %(userId)s", "user_id": "User ID: %(userId)s",
"user_identity": "Cryptographic identity",
"user_identity_unknown": "Unknown",
"user_no_avatar": "Avatar: <i>None</i>", "user_no_avatar": "Avatar: <i>None</i>",
"user_no_displayname": "Displayname: <i>None</i>", "user_no_displayname": "Displayname: <i>None</i>",
"user_read_up_to": "User read up to: ", "user_read_up_to": "User read up to: ",
+1
View File
@@ -125,6 +125,7 @@ export function createTestClient(): MatrixClient {
getOwnDeviceKeys: vi.fn().mockResolvedValue({ ed25519: "ed25519", curve25519: "curve25519" }), getOwnDeviceKeys: vi.fn().mockResolvedValue({ ed25519: "ed25519", curve25519: "curve25519" }),
getUserDeviceInfo: vi.fn().mockResolvedValue(new Map()), getUserDeviceInfo: vi.fn().mockResolvedValue(new Map()),
getUserVerificationStatus: vi.fn(), getUserVerificationStatus: vi.fn(),
getUserCrossSigningKeys: vi.fn().mockResolvedValue(null),
getDeviceVerificationStatus: vi.fn(), getDeviceVerificationStatus: vi.fn(),
resetKeyBackup: vi.fn(), resetKeyBackup: vi.fn(),
isEncryptionEnabledInRoom: vi.fn().mockResolvedValue(false), isEncryptionEnabledInRoom: vi.fn().mockResolvedValue(false),
@@ -654,6 +654,14 @@ exports[`<Users /> should render a single user 1`] = `
</li> </li>
</ul> </ul>
</section> </section>
<section>
<h2>
Cryptographic identity
</h2>
<i>
Unknown
</i>
</section>
</div> </div>
<div <div
class="mx_Dialog_buttons" class="mx_Dialog_buttons"