diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 8b23455967b..0f122b2d5f9 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -1631,8 +1631,12 @@ export default class MatrixChat extends React.PureComponent { cli.on(CryptoEvent.KeyBackupFailed, async (errcode): Promise => { let haveNewVersion: boolean | undefined; let newVersionInfo: KeyBackupInfo | null = null; + const keyBackupEnabled = Boolean( + cli.getCrypto() && (await cli.getCrypto()?.getActiveSessionBackupVersion()) !== null, + ); + // if key backup is still enabled, there must be a new backup in place - if (cli.getKeyBackupEnabled()) { + if (keyBackupEnabled) { haveNewVersion = true; } else { // otherwise check the server to see if there's a new one @@ -1650,7 +1654,6 @@ export default class MatrixChat extends React.PureComponent { import( "../../async-components/views/dialogs/security/NewRecoveryMethodDialog" ) as unknown as Promise, - { newVersionInfo: newVersionInfo! }, ); } else { Modal.createDialogAsync( diff --git a/test/unit-tests/components/structures/MatrixChat-test.tsx b/test/unit-tests/components/structures/MatrixChat-test.tsx index 4b10043ad2e..da6e005a23d 100644 --- a/test/unit-tests/components/structures/MatrixChat-test.tsx +++ b/test/unit-tests/components/structures/MatrixChat-test.tsx @@ -22,7 +22,7 @@ import { logger } from "matrix-js-sdk/src/logger"; import { OidcError } from "matrix-js-sdk/src/oidc/error"; import { BearerTokenResponse } from "matrix-js-sdk/src/oidc/validate"; import { defer, IDeferred, sleep } from "matrix-js-sdk/src/utils"; -import { UserVerificationStatus } from "matrix-js-sdk/src/crypto-api"; +import { CryptoEvent, UserVerificationStatus } from "matrix-js-sdk/src/crypto-api"; import MatrixChat from "../../../../src/components/structures/MatrixChat"; import * as StorageAccess from "../../../../src/utils/StorageAccess"; @@ -135,6 +135,7 @@ describe("", () => { getVersion: jest.fn().mockReturnValue("1"), setDeviceIsolationMode: jest.fn(), userHasCrossSigningKeys: jest.fn(), + getActiveSessionBackupVersion: jest.fn().mockResolvedValue(null), }), // This needs to not finish immediately because we need to test the screen appears bootstrapCrossSigning: jest.fn().mockImplementation(() => bootstrapDeferred.promise), @@ -1515,4 +1516,22 @@ describe("", () => { expect(screen.getByTestId("mobile-register")).toBeInTheDocument(); }); }); + + describe("when key backup failed", () => { + it("should show the new recovery method dialog", async () => { + jest.mock("../../../../src/async-components/views/dialogs/security/NewRecoveryMethodDialog", () => ({ + __esModule: true, + default: () => mocked dialog, + })); + jest.spyOn(mockClient.getCrypto()!, "getActiveSessionBackupVersion").mockResolvedValue("version"); + + getComponent({}); + defaultDispatcher.dispatch({ + action: "will_start_client", + }); + await flushPromises(); + mockClient.emit(CryptoEvent.KeyBackupFailed, "error code"); + await waitFor(() => expect(screen.getByText("mocked dialog")).toBeInTheDocument()); + }); + }); });