1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-23 17:02:25 +03:00

Element-R: silence log errors when viewing a pending event (#3824)

* Element-R: silence log errors when viewing a pending event

Fixes the second half of vector-im/element-web#26272

* Update spec/integ/crypto/crypto.spec.ts
This commit is contained in:
Richard van der Hoff
2023-10-25 10:11:40 +01:00
committed by GitHub
parent c41949de15
commit 6f82f08c7b
2 changed files with 114 additions and 6 deletions

View File

@@ -57,7 +57,7 @@ import {
import { DeviceInfo } from "../../../src/crypto/deviceinfo"; import { DeviceInfo } from "../../../src/crypto/deviceinfo";
import { E2EKeyReceiver } from "../../test-utils/E2EKeyReceiver"; import { E2EKeyReceiver } from "../../test-utils/E2EKeyReceiver";
import { ISyncResponder, SyncResponder } from "../../test-utils/SyncResponder"; import { ISyncResponder, SyncResponder } from "../../test-utils/SyncResponder";
import { escapeRegExp } from "../../../src/utils"; import { defer, escapeRegExp } from "../../../src/utils";
import { downloadDeviceToJsDevice } from "../../../src/rust-crypto/device-converter"; import { downloadDeviceToJsDevice } from "../../../src/rust-crypto/device-converter";
import { flushPromises } from "../../test-utils/flushPromises"; import { flushPromises } from "../../test-utils/flushPromises";
import { import {
@@ -66,13 +66,19 @@ import {
mockSetupMegolmBackupRequests, mockSetupMegolmBackupRequests,
} from "../../test-utils/mockEndpoints"; } from "../../test-utils/mockEndpoints";
import { AddSecretStorageKeyOpts } from "../../../src/secret-storage"; import { AddSecretStorageKeyOpts } from "../../../src/secret-storage";
import { CrossSigningKey, CryptoCallbacks, KeyBackupInfo } from "../../../src/crypto-api"; import {
CrossSigningKey,
CryptoCallbacks,
EventShieldColour,
EventShieldReason,
KeyBackupInfo,
} from "../../../src/crypto-api";
import { E2EKeyResponder } from "../../test-utils/E2EKeyResponder"; import { E2EKeyResponder } from "../../test-utils/E2EKeyResponder";
import { DecryptionError } from "../../../src/crypto/algorithms"; import { DecryptionError } from "../../../src/crypto/algorithms";
import { IKeyBackup } from "../../../src/crypto/backup"; import { IKeyBackup } from "../../../src/crypto/backup";
import { import {
createOlmSession,
createOlmAccount, createOlmAccount,
createOlmSession,
encryptGroupSessionKey, encryptGroupSessionKey,
encryptMegolmEvent, encryptMegolmEvent,
encryptMegolmEventRawPlainText, encryptMegolmEventRawPlainText,
@@ -1700,6 +1706,105 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
await sendEventPromise; await sendEventPromise;
}); });
describe("getEncryptionInfoForEvent", () => {
it("handles outgoing events", async () => {
aliceClient.setGlobalErrorOnUnknownDevices(false);
expectAliceKeyQuery({ device_keys: { "@alice:localhost": {} }, failures: {} });
await startClientAndAwaitFirstSync();
// Alice shares a room with Bob
syncResponder.sendOrQueueSyncResponse(getSyncResponse(["@bob:xyz"]));
await syncPromise(aliceClient);
// Once we send the message, Alice will check Bob's device list (twice, because reasons) ...
expectAliceKeyQuery(getTestKeysQueryResponse("@bob:xyz"));
expectAliceKeyQuery(getTestKeysQueryResponse("@bob:xyz"));
// ... and claim one of his OTKs ...
expectAliceKeyClaim(getTestKeysClaimResponse("@bob:xyz"));
// ... and send an m.room_key message ...
const inboundGroupSessionPromise = expectSendRoomKey("@bob:xyz", testOlmAccount);
// ... and finally, send the room key. We block the response until `sendRoomMessageDefer` completes.
const sendRoomMessageDefer = defer<MockResponse>();
const reqProm = new Promise<IContent>((resolve) => {
fetchMock.putOnce(
new RegExp("/send/m.room.encrypted/"),
async (url: string, opts: RequestInit): Promise<MockResponse> => {
resolve(JSON.parse(opts.body as string));
return await sendRoomMessageDefer.promise;
},
{
// append to the list of intercepts on this path (since we have some tests that call
// this function multiple times)
overwriteRoutes: false,
},
);
});
// Now we start to send the message
const sendProm = aliceClient.sendTextMessage(testData.TEST_ROOM_ID, "test");
// and wait for the outgoing requests
const inboundGroupSession = await inboundGroupSessionPromise;
const encryptedMessageContent = await reqProm;
const msg: any = inboundGroupSession.decrypt(encryptedMessageContent!.ciphertext);
logger.log("Decrypted received megolm message", msg);
// at this point, the request to send the room message has been made, but not completed.
// get hold of the pending event, and see what getEncryptionInfoForEvent makes of it
const pending = aliceClient.getRoom(testData.TEST_ROOM_ID)!.getPendingEvents();
expect(pending.length).toEqual(1);
const encInfo = await aliceClient.getCrypto()!.getEncryptionInfoForEvent(pending[0]);
expect(encInfo!.shieldColour).toEqual(EventShieldColour.NONE);
expect(encInfo!.shieldReason).toBeNull();
// release the send request
const resp = { event_id: "$event_id" };
sendRoomMessageDefer.resolve(resp);
expect(await sendProm).toEqual(resp);
// still pending at this point
expect(aliceClient.getRoom(testData.TEST_ROOM_ID)!.getPendingEvents().length).toEqual(1);
// echo the event back
const fullEvent = {
event_id: "$event_id",
type: "m.room.encrypted",
sender: aliceClient.getUserId(),
origin_server_ts: Date.now(),
content: encryptedMessageContent,
};
syncResponder.sendOrQueueSyncResponse({
next_batch: 1,
rooms: { join: { [testData.TEST_ROOM_ID]: { timeline: { events: [fullEvent] } } } },
});
await syncPromise(aliceClient);
const timelineEvents = aliceClient.getRoom(testData.TEST_ROOM_ID)!.getLiveTimeline()!.getEvents();
const lastEvent = timelineEvents[timelineEvents.length - 1];
expect(lastEvent.getId()).toEqual("$event_id");
// now check getEncryptionInfoForEvent again
const encInfo2 = await aliceClient.getCrypto()!.getEncryptionInfoForEvent(lastEvent);
let expectedEncryptionInfo;
if (backend === "rust-sdk") {
// rust crypto does not trust its own device until it is cross-signed.
expectedEncryptionInfo = {
shieldColour: EventShieldColour.RED,
shieldReason: EventShieldReason.UNSIGNED_DEVICE,
};
} else {
expectedEncryptionInfo = {
shieldColour: EventShieldColour.NONE,
shieldReason: null,
};
}
expect(encInfo2).toEqual(expectedEncryptionInfo);
});
});
describe("Lazy-loading member lists", () => { describe("Lazy-loading member lists", () => {
let p2pSession: Olm.Session; let p2pSession: Olm.Session;

View File

@@ -29,7 +29,7 @@ import { ClientPrefix, IHttpOpts, MatrixHttpApi, Method } from "../http-api";
import { RoomEncryptor } from "./RoomEncryptor"; import { RoomEncryptor } from "./RoomEncryptor";
import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProcessor"; import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProcessor";
import { KeyClaimManager } from "./KeyClaimManager"; import { KeyClaimManager } from "./KeyClaimManager";
import { MapWithDefault, encodeUri } from "../utils"; import { encodeUri, MapWithDefault } from "../utils";
import { import {
BackupTrustInfo, BackupTrustInfo,
BootstrapCrossSigningOpts, BootstrapCrossSigningOpts,
@@ -267,8 +267,6 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
* @param event - event to inspect * @param event - event to inspect
*/ */
public getEventEncryptionInfo(event: MatrixEvent): IEncryptedEventInfo { public getEventEncryptionInfo(event: MatrixEvent): IEncryptedEventInfo {
// TODO: make this work properly. Or better, replace it.
const ret: Partial<IEncryptedEventInfo> = {}; const ret: Partial<IEncryptedEventInfo> = {};
ret.senderKey = event.getSenderKey() ?? undefined; ret.senderKey = event.getSenderKey() ?? undefined;
@@ -1654,6 +1652,11 @@ class EventDecryptor {
return null; return null;
} }
// special-case outgoing events, which the rust crypto-sdk will barf on
if (event.status !== null) {
return { shieldColour: EventShieldColour.NONE, shieldReason: null };
}
const encryptionInfo = await this.olmMachine.getRoomEventEncryptionInfo( const encryptionInfo = await this.olmMachine.getRoomEventEncryptionInfo(
stringifyEvent(event), stringifyEvent(event),
new RustSdkCryptoJs.RoomId(event.getRoomId()!), new RustSdkCryptoJs.RoomId(event.getRoomId()!),