diff --git a/extensions/matrix/src/matrix/sdk.test.ts b/extensions/matrix/src/matrix/sdk.test.ts index 1f3d992d5d7..7116f8865cd 100644 --- a/extensions/matrix/src/matrix/sdk.test.ts +++ b/extensions/matrix/src/matrix/sdk.test.ts @@ -1323,6 +1323,39 @@ describe("MatrixClient crypto bootstrapping", () => { }); }); + it("catches and logs repair bootstrap failure when UIA is unavailable without password", async () => { + matrixJsClient.getCrypto = vi.fn(() => ({ on: vi.fn() })); + const client = new MatrixClient("https://matrix.example.org", "token", { + encryption: true, + // no password + }); + const uiaError = new Error("Interactive auth required"); + const bootstrapSpy = vi + .fn() + .mockResolvedValueOnce({ + crossSigningReady: false, + crossSigningPublished: false, + ownDeviceVerified: false, + }) + .mockRejectedValueOnce(uiaError); + await ( + client as unknown as { + ensureCryptoSupportInitialized: () => Promise; + } + ).ensureCryptoSupportInitialized(); + ( + client as unknown as { + cryptoBootstrapper: { bootstrap: typeof bootstrapSpy }; + } + ).cryptoBootstrapper.bootstrap = bootstrapSpy; + + // start() must NOT throw even when the repair bootstrap fails + await expect(client.start()).resolves.not.toThrow(); + + // repair was attempted + expect(bootstrapSpy).toHaveBeenCalledTimes(2); + }); + it("provides secret storage callbacks and resolves stored recovery key", async () => { const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "matrix-sdk-test-")); const recoveryKeyPath = path.join(tmpDir, "recovery-key.json");