Matrix-js: register verification listeners before bootstrap

This commit is contained in:
Gustavo Madeira Santana
2026-02-23 00:51:03 -05:00
parent 1a7ea655bf
commit 0bbd8ef439
2 changed files with 28 additions and 1 deletions

View File

@@ -257,4 +257,22 @@ describe("MatrixCryptoBootstrapper", () => {
);
expect(verificationRequest.accept).toHaveBeenCalledTimes(1);
});
it("registers verification listeners only once across repeated bootstrap calls", async () => {
const deps = createBootstrapperDeps();
const crypto = createCryptoApi({
getDeviceVerificationStatus: vi.fn(async () => ({
isVerified: () => true,
})),
});
const bootstrapper = new MatrixCryptoBootstrapper(
deps as unknown as MatrixCryptoBootstrapperDeps<MatrixRawEvent>,
);
await bootstrapper.bootstrap(crypto);
await bootstrapper.bootstrap(crypto);
expect(crypto.on).toHaveBeenCalledTimes(1);
expect(deps.decryptBridge.bindCryptoRetrySignals).toHaveBeenCalledTimes(1);
});
});

View File

@@ -34,6 +34,8 @@ export type MatrixCryptoBootstrapResult = {
};
export class MatrixCryptoBootstrapper<TRawEvent extends MatrixRawEvent> {
private verificationHandlerRegistered = false;
constructor(private readonly deps: MatrixCryptoBootstrapperDeps<TRawEvent>) {}
async bootstrap(
@@ -41,6 +43,9 @@ export class MatrixCryptoBootstrapper<TRawEvent extends MatrixRawEvent> {
options: MatrixCryptoBootstrapOptions = {},
): Promise<MatrixCryptoBootstrapResult> {
const strict = options.strict === true;
// Register verification listeners before expensive bootstrap work so incoming requests
// are not missed during startup.
this.registerVerificationRequestHandler(crypto);
await this.bootstrapSecretStorage(crypto, strict);
const crossSigning = await this.bootstrapCrossSigning(crypto, {
forceResetCrossSigning: options.forceResetCrossSigning === true,
@@ -48,7 +53,6 @@ export class MatrixCryptoBootstrapper<TRawEvent extends MatrixRawEvent> {
});
await this.bootstrapSecretStorage(crypto, strict);
const ownDeviceVerified = await this.ensureOwnDeviceTrust(crypto, strict);
this.registerVerificationRequestHandler(crypto);
return {
crossSigningReady: crossSigning.ready,
crossSigningPublished: crossSigning.published,
@@ -209,6 +213,11 @@ export class MatrixCryptoBootstrapper<TRawEvent extends MatrixRawEvent> {
}
private registerVerificationRequestHandler(crypto: MatrixCryptoBootstrapApi): void {
if (this.verificationHandlerRegistered) {
return;
}
this.verificationHandlerRegistered = true;
// Auto-accept incoming verification requests from other users/devices.
crypto.on(CryptoEvent.VerificationRequestReceived, async (request) => {
const verificationRequest = request as MatrixVerificationRequestLike;