You've already forked matrix-js-sdk
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:
committed by
GitHub
parent
c41949de15
commit
6f82f08c7b
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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()!),
|
||||||
|
|||||||
Reference in New Issue
Block a user