1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-07-31 15:24:23 +03:00

Element-R: await /keys/query during Verification requests (#3932)

This commit is contained in:
Richard van der Hoff
2023-12-05 11:18:12 +00:00
committed by GitHub
parent f31e83fd03
commit 41878c7a43
3 changed files with 55 additions and 6 deletions

View File

@ -62,9 +62,13 @@ describe("VerificationRequest", () => {
describe("startVerification", () => { describe("startVerification", () => {
let request: RustVerificationRequest; let request: RustVerificationRequest;
let machine: Mocked<RustSdkCryptoJs.OlmMachine>;
let inner: Mocked<RustSdkCryptoJs.VerificationRequest>;
beforeEach(() => { beforeEach(() => {
request = makeTestRequest(); inner = makeMockedInner();
machine = { getDevice: jest.fn() } as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
request = makeTestRequest(inner, machine);
}); });
it("does not permit methods other than SAS", async () => { it("does not permit methods other than SAS", async () => {
@ -73,7 +77,15 @@ describe("VerificationRequest", () => {
); );
}); });
it("raises an error if the other device is unknown", async () => {
await expect(request.startVerification("m.sas.v1")).rejects.toThrow(
"startVerification(): other device is unknown",
);
});
it("raises an error if starting verification does not produce a verifier", async () => { it("raises an error if starting verification does not produce a verifier", async () => {
jest.spyOn(inner, "otherDeviceId", "get").mockReturnValue(new RustSdkCryptoJs.DeviceId("other_device"));
machine.getDevice.mockResolvedValue({} as RustSdkCryptoJs.Device);
await expect(request.startVerification("m.sas.v1")).rejects.toThrow( await expect(request.startVerification("m.sas.v1")).rejects.toThrow(
"Still no verifier after startSas() call", "Still no verifier after startSas() call",
); );
@ -118,11 +130,13 @@ describe("isVerificationEvent", () => {
/** build a RustVerificationRequest with default parameters */ /** build a RustVerificationRequest with default parameters */
function makeTestRequest( function makeTestRequest(
inner?: RustSdkCryptoJs.VerificationRequest, inner?: RustSdkCryptoJs.VerificationRequest,
olmMachine?: RustSdkCryptoJs.OlmMachine,
outgoingRequestProcessor?: OutgoingRequestProcessor, outgoingRequestProcessor?: OutgoingRequestProcessor,
): RustVerificationRequest { ): RustVerificationRequest {
inner ??= makeMockedInner(); inner ??= makeMockedInner();
olmMachine ??= {} as RustSdkCryptoJs.OlmMachine;
outgoingRequestProcessor ??= {} as OutgoingRequestProcessor; outgoingRequestProcessor ??= {} as OutgoingRequestProcessor;
return new RustVerificationRequest(inner, outgoingRequestProcessor, []); return new RustVerificationRequest(olmMachine, inner, outgoingRequestProcessor, []);
} }
/** Mock up a rust-side VerificationRequest */ /** Mock up a rust-side VerificationRequest */
@ -133,5 +147,8 @@ function makeMockedInner(): Mocked<RustSdkCryptoJs.VerificationRequest> {
phase: jest.fn().mockReturnValue(RustSdkCryptoJs.VerificationRequestPhase.Created), phase: jest.fn().mockReturnValue(RustSdkCryptoJs.VerificationRequestPhase.Created),
isPassive: jest.fn().mockReturnValue(false), isPassive: jest.fn().mockReturnValue(false),
timeRemainingMillis: jest.fn(), timeRemainingMillis: jest.fn(),
get otherDeviceId() {
return undefined;
},
} as unknown as Mocked<RustSdkCryptoJs.VerificationRequest>; } as unknown as Mocked<RustSdkCryptoJs.VerificationRequest>;
} }

View File

@ -940,6 +940,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
.map( .map(
(request) => (request) =>
new RustVerificationRequest( new RustVerificationRequest(
this.olmMachine,
request, request,
this.outgoingRequestProcessor, this.outgoingRequestProcessor,
this._supportedVerificationMethods, this._supportedVerificationMethods,
@ -970,6 +971,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
if (request) { if (request) {
return new RustVerificationRequest( return new RustVerificationRequest(
this.olmMachine,
request, request,
this.outgoingRequestProcessor, this.outgoingRequestProcessor,
this._supportedVerificationMethods, this._supportedVerificationMethods,
@ -1005,6 +1007,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
methods, methods,
); );
return new RustVerificationRequest( return new RustVerificationRequest(
this.olmMachine,
request, request,
this.outgoingRequestProcessor, this.outgoingRequestProcessor,
this._supportedVerificationMethods, this._supportedVerificationMethods,
@ -1080,6 +1083,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
); );
await this.outgoingRequestProcessor.makeOutgoingRequest(outgoingRequest); await this.outgoingRequestProcessor.makeOutgoingRequest(outgoingRequest);
return new RustVerificationRequest( return new RustVerificationRequest(
this.olmMachine,
request, request,
this.outgoingRequestProcessor, this.outgoingRequestProcessor,
this._supportedVerificationMethods, this._supportedVerificationMethods,
@ -1118,6 +1122,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
); );
await this.outgoingRequestProcessor.makeOutgoingRequest(outgoingRequest); await this.outgoingRequestProcessor.makeOutgoingRequest(outgoingRequest);
return new RustVerificationRequest( return new RustVerificationRequest(
this.olmMachine,
request, request,
this.outgoingRequestProcessor, this.outgoingRequestProcessor,
this._supportedVerificationMethods, this._supportedVerificationMethods,
@ -1405,7 +1410,12 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
if (request) { if (request) {
this.emit( this.emit(
CryptoEvent.VerificationRequestReceived, CryptoEvent.VerificationRequestReceived,
new RustVerificationRequest(request, this.outgoingRequestProcessor, this._supportedVerificationMethods), new RustVerificationRequest(
this.olmMachine,
request,
this.outgoingRequestProcessor,
this._supportedVerificationMethods,
),
); );
} }
} }
@ -1622,6 +1632,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
this.emit( this.emit(
CryptoEvent.VerificationRequestReceived, CryptoEvent.VerificationRequestReceived,
new RustVerificationRequest( new RustVerificationRequest(
this.olmMachine,
request, request,
this.outgoingRequestProcessor, this.outgoingRequestProcessor,
this._supportedVerificationMethods, this._supportedVerificationMethods,

View File

@ -57,11 +57,13 @@ export class RustVerificationRequest
/** /**
* Construct a new RustVerificationRequest to wrap the rust-level `VerificationRequest`. * Construct a new RustVerificationRequest to wrap the rust-level `VerificationRequest`.
* *
* @param inner - VerificationRequest from the Rust SDK * @param olmMachine - The `OlmMachine` from the underlying rust crypto sdk.
* @param outgoingRequestProcessor - `OutgoingRequestProcessor` to use for making outgoing HTTP requests * @param inner - VerificationRequest from the Rust SDK.
* @param supportedVerificationMethods - Verification methods to use when `accept()` is called * @param outgoingRequestProcessor - `OutgoingRequestProcessor` to use for making outgoing HTTP requests.
* @param supportedVerificationMethods - Verification methods to use when `accept()` is called.
*/ */
public constructor( public constructor(
private readonly olmMachine: RustSdkCryptoJs.OlmMachine,
private readonly inner: RustSdkCryptoJs.VerificationRequest, private readonly inner: RustSdkCryptoJs.VerificationRequest,
private readonly outgoingRequestProcessor: OutgoingRequestProcessor, private readonly outgoingRequestProcessor: OutgoingRequestProcessor,
private readonly supportedVerificationMethods: string[], private readonly supportedVerificationMethods: string[],
@ -135,6 +137,15 @@ export class RustVerificationRequest
return this.inner.otherDeviceId?.toString(); return this.inner.otherDeviceId?.toString();
} }
/** Get the other device involved in the verification, if it is known */
private async getOtherDevice(): Promise<undefined | RustSdkCryptoJs.Device> {
const otherDeviceId = this.inner.otherDeviceId;
if (!otherDeviceId) {
return undefined;
}
return await this.olmMachine.getDevice(this.inner.otherUserId, otherDeviceId, 5);
}
/** True if the other party in this request is one of this user's own devices. */ /** True if the other party in this request is one of this user's own devices. */
public get isSelfVerification(): boolean { public get isSelfVerification(): boolean {
return this.inner.isSelfVerification(); return this.inner.isSelfVerification();
@ -322,6 +333,11 @@ export class RustVerificationRequest
throw new Error(`Unsupported verification method ${method}`); throw new Error(`Unsupported verification method ${method}`);
} }
// make sure that we have a list of the other user's devices (workaround https://github.com/matrix-org/matrix-rust-sdk/issues/2896)
if (!(await this.getOtherDevice())) {
throw new Error("startVerification(): other device is unknown");
}
const res: const res:
| [RustSdkCryptoJs.Sas, RustSdkCryptoJs.RoomMessageRequest | RustSdkCryptoJs.ToDeviceRequest] | [RustSdkCryptoJs.Sas, RustSdkCryptoJs.RoomMessageRequest | RustSdkCryptoJs.ToDeviceRequest]
| undefined = await this.inner.startSas(); | undefined = await this.inner.startSas();
@ -392,6 +408,11 @@ export class RustVerificationRequest
* Implementation of {@link Crypto.VerificationRequest#generateQRCode}. * Implementation of {@link Crypto.VerificationRequest#generateQRCode}.
*/ */
public async generateQRCode(): Promise<Buffer | undefined> { public async generateQRCode(): Promise<Buffer | undefined> {
// make sure that we have a list of the other user's devices (workaround https://github.com/matrix-org/matrix-rust-sdk/issues/2896)
if (!(await this.getOtherDevice())) {
throw new Error("generateQRCode(): other device is unknown");
}
const innerVerifier: RustSdkCryptoJs.Qr | undefined = await this.inner.generateQrCode(); const innerVerifier: RustSdkCryptoJs.Qr | undefined = await this.inner.generateQrCode();
// If we are unable to generate a QRCode, we return undefined // If we are unable to generate a QRCode, we return undefined
if (!innerVerifier) return; if (!innerVerifier) return;