{
public constructor(props: IProps) {
super(props);
+
+ const client = MatrixClientPeg.safeGet();
+ const crypto = client.getCrypto();
+ if (!crypto) {
+ this.state = { deviceIdentityKey: null };
+ } else {
+ this.state = { deviceIdentityKey: undefined };
+ crypto
+ .getOwnDeviceKeys()
+ .then((keys) => {
+ this.setState({ deviceIdentityKey: keys.ed25519 });
+ })
+ .catch((e) => {
+ logger.error(`CryptographyPanel: Error fetching own device keys: ${e}`);
+ this.setState({ deviceIdentityKey: null });
+ });
+ }
}
public render(): React.ReactNode {
const client = MatrixClientPeg.safeGet();
const deviceId = client.deviceId;
- let identityKey = client.getDeviceEd25519Key();
- if (!identityKey) {
+ let identityKey = this.state.deviceIdentityKey;
+ if (identityKey === undefined) {
+ // Should show a spinner here really, but since this will be very transitional, I can't be doing with the
+ // necessary styling.
+ identityKey = "...";
+ } else if (identityKey === null) {
identityKey = _t("encryption|not_supported");
} else {
identityKey = FormattingUtils.formatCryptoKey(identityKey);
}
let importExportButtons: JSX.Element | undefined;
- if (client.isCryptoEnabled()) {
+ if (client.getCrypto()) {
importExportButtons = (
@@ -68,20 +97,22 @@ export default class CryptographyPanel extends React.Component {
-
- {_t("settings|security|session_id")} |
-
- {deviceId}
- |
-
-
- {_t("settings|security|session_key")} |
-
-
- {identityKey}
-
- |
-
+
+
+ {_t("settings|security|session_id")} |
+
+ {deviceId}
+ |
+
+
+ {_t("settings|security|session_key")} |
+
+
+ {identityKey}
+
+ |
+
+
{importExportButtons}
diff --git a/test/components/views/settings/CryptographyPanel-test.tsx b/test/components/views/settings/CryptographyPanel-test.tsx
index a993829e37..388f27e62f 100644
--- a/test/components/views/settings/CryptographyPanel-test.tsx
+++ b/test/components/views/settings/CryptographyPanel-test.tsx
@@ -9,13 +9,15 @@ Please see LICENSE files in the repository root for full details.
import React from "react";
import { render } from "@testing-library/react";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
+import { mocked } from "jest-mock";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import * as TestUtils from "../../../test-utils";
import CryptographyPanel from "../../../../src/components/views/settings/CryptographyPanel";
+import { flushPromises } from "../../../test-utils";
describe("CryptographyPanel", () => {
- it("shows the session ID and key", () => {
+ it("shows the session ID and key", async () => {
const sessionId = "ABCDEFGHIJ";
const sessionKey = "AbCDeFghIJK7L/m4nOPqRSTUVW4xyzaBCDef6gHIJkl";
const sessionKeyFormatted = "AbCD eFgh IJK7 L/m4 nOPq RSTU VW4x yzaB CDef 6gHI Jkl";
@@ -23,7 +25,8 @@ describe("CryptographyPanel", () => {
TestUtils.stubClient();
const client: MatrixClient = MatrixClientPeg.safeGet();
client.deviceId = sessionId;
- client.getDeviceEd25519Key = () => sessionKey;
+
+ mocked(client.getCrypto()!.getOwnDeviceKeys).mockResolvedValue({ ed25519: sessionKey, curve25519: "1234" });
// When we render the CryptographyPanel
const rendered = render();
@@ -32,6 +35,35 @@ describe("CryptographyPanel", () => {
const codes = rendered.container.querySelectorAll("code");
expect(codes.length).toEqual(2);
expect(codes[0].innerHTML).toEqual(sessionId);
+
+ // Initially a placeholder
+ expect(codes[1].innerHTML).toEqual("...");
+
+ // Then the actual key
+ await flushPromises();
expect(codes[1].innerHTML).toEqual(sessionKeyFormatted);
});
+
+ it("handles errors fetching session key", async () => {
+ const sessionId = "ABCDEFGHIJ";
+
+ TestUtils.stubClient();
+ const client: MatrixClient = MatrixClientPeg.safeGet();
+ client.deviceId = sessionId;
+
+ mocked(client.getCrypto()!.getOwnDeviceKeys).mockRejectedValue(new Error("bleh"));
+
+ // When we render the CryptographyPanel
+ const rendered = render();
+
+ // Then it displays info about the user's session
+ const codes = rendered.container.querySelectorAll("code");
+
+ // Initially a placeholder
+ expect(codes[1].innerHTML).toEqual("...");
+
+ // Then "not supported key
+ await flushPromises();
+ expect(codes[1].innerHTML).toEqual("<not supported>");
+ });
});
diff --git a/test/components/views/settings/tabs/user/__snapshots__/SecurityUserSettingsTab-test.tsx.snap b/test/components/views/settings/tabs/user/__snapshots__/SecurityUserSettingsTab-test.tsx.snap
index 4ccca2a02c..86874f437e 100644
--- a/test/components/views/settings/tabs/user/__snapshots__/SecurityUserSettingsTab-test.tsx.snap
+++ b/test/components/views/settings/tabs/user/__snapshots__/SecurityUserSettingsTab-test.tsx.snap
@@ -314,32 +314,52 @@ exports[` renders security section 1`] = `
-
-
- Session ID:
- |
-
-
- |
-
-
-
- Session key:
- |
-
-
-
- <not supported>
-
-
- |
-
+
+
+
+ Session ID:
+ |
+
+
+ |
+
+
+
+ Session key:
+ |
+
+
+
+ ...
+
+
+ |
+
+
+
diff --git a/test/test-utils/client.ts b/test/test-utils/client.ts
index d4f2878004..19625043e1 100644
--- a/test/test-utils/client.ts
+++ b/test/test-utils/client.ts
@@ -135,7 +135,6 @@ export const mockClientMethodsDevice = (
deviceId = "test-device-id",
): Partial, unknown>> => ({
getDeviceId: jest.fn().mockReturnValue(deviceId),
- getDeviceEd25519Key: jest.fn(),
getDevices: jest.fn().mockResolvedValue({ devices: [] }),
});
@@ -164,10 +163,9 @@ export const mockClientMethodsCrypto = (): Partial<
isSecretStorageReady: jest.fn(),
getSessionBackupPrivateKey: jest.fn(),
getVersion: jest.fn().mockReturnValue("Version 0"),
- getOwnDeviceKeys: jest.fn(),
+ getOwnDeviceKeys: jest.fn().mockReturnValue(new Promise(() => {})),
getCrossSigningKeyId: jest.fn(),
}),
- getDeviceEd25519Key: jest.fn(),
});
export const mockClientMethodsRooms = (rooms: Room[] = []): Partial, unknown>> => ({
diff --git a/test/test-utils/test-utils.ts b/test/test-utils/test-utils.ts
index 092f30fb52..b0c3dda279 100644
--- a/test/test-utils/test-utils.ts
+++ b/test/test-utils/test-utils.ts
@@ -124,6 +124,7 @@ export function createTestClient(): MatrixClient {
},
},
getCrypto: jest.fn().mockReturnValue({
+ getOwnDeviceKeys: jest.fn(),
getUserDeviceInfo: jest.fn(),
getUserVerificationStatus: jest.fn(),
getDeviceVerificationStatus: jest.fn(),