diff --git a/src/pairing.spec.ts b/src/pairing.spec.ts index bcd13bf..e1ec8b5 100644 --- a/src/pairing.spec.ts +++ b/src/pairing.spec.ts @@ -31,8 +31,11 @@ describe("js-noise: pairing object", () => { }; const decoderMap: { [key: string]: Decoder } = {}; const receiver = { - subscribe(decoder: Decoder): void { - decoderMap[decoder.contentTopic] = decoder; + subscribe(decoder: Decoder): Promise { + return new Promise((resolve) => { + decoderMap[decoder.contentTopic] = decoder; + resolve(); + }); }, async nextMessage(contentTopic: string): Promise { const msg = await pEvent(msgEmitter, contentTopic); diff --git a/src/pairing.ts b/src/pairing.ts index 9c8f44d..d000431 100644 --- a/src/pairing.ts +++ b/src/pairing.ts @@ -12,20 +12,20 @@ import { NoiseHandshakeMessage, NoiseSecureTransferDecoder, NoiseSecureTransferEncoder, -} from "./codec"; -import { commitPublicKey, generateX25519KeyPair } from "./crypto"; -import { Handshake, HandshakeResult, HandshakeStepResult, MessageNametagError } from "./handshake"; -import { NoiseHandshakePatterns } from "./patterns"; -import { MessageNametagLength } from "./payload"; -import { NoisePublicKey } from "./publickey"; -import { QR } from "./qr"; +} from "./codec.js"; +import { commitPublicKey, generateX25519KeyPair } from "./crypto.js"; +import { Handshake, HandshakeResult, HandshakeStepResult, MessageNametagError } from "./handshake.js"; +import { NoiseHandshakePatterns } from "./patterns.js"; +import { MessageNametagLength } from "./payload.js"; +import { NoisePublicKey } from "./publickey.js"; +import { QR } from "./qr.js"; export interface Sender { publish(encoder: Encoder, msg: Message): Promise; } export interface Receiver { - subscribe(decoder: Decoder): void; + subscribe(decoder: Decoder): Promise; // next message should return messages received in a content topic // messages should be kept in a queue, meaning that nextMessage @@ -34,6 +34,10 @@ export interface Receiver { nextMessage(contentTopic: string): Promise; } +function delay(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + const rng = new HMACDRBG(); export class InitiatorParameters { @@ -163,7 +167,9 @@ export class WakuPairing { return step; } catch (err) { if (err instanceof MessageNametagError) { - console.error("Unexpected message nametag", err.expectedNametag, err.actualNametag); + console.debug("Unexpected message nametag", err.expectedNametag, err.actualNametag); + } else { + throw err; } } } @@ -172,6 +178,10 @@ export class WakuPairing { } private async initiatorHandshake(): Promise<[NoiseSecureTransferEncoder, NoiseSecureTransferDecoder]> { + // Subscribe to the contact content topic + const decoder = new NoiseHandshakeDecoder(this.contentTopic); + await this.receiver.subscribe(decoder); + // The handshake initiator writes a Waku2 payload v2 containing the handshake message // and the (encrypted) transport message // The message is sent with a messageNametag equal to the one received through the QR code @@ -187,9 +197,11 @@ export class WakuPairing { // We generate an authorization code using the handshake state // this check has to be confirmed with a user interaction, comparing auth codes in both ends + const confirmationPromise = this.isAuthCodeConfirmed(); + await delay(100); this.eventEmitter.emit("authCodeGenerated", this.handshake.genAuthcode()); - - const confirmed = await this.isAuthCodeConfirmed(); + console.log("Waiting for authcode confirmation..."); + const confirmed = await confirmationPromise; if (!confirmed) { throw new Error("authcode is not confirmed"); } @@ -228,7 +240,7 @@ export class WakuPairing { private async receiverHandshake(): Promise<[NoiseSecureTransferEncoder, NoiseSecureTransferDecoder]> { // Subscribe to the contact content topic const decoder = new NoiseHandshakeDecoder(this.contentTopic); - this.receiver.subscribe(decoder); + await this.receiver.subscribe(decoder); // the received reads the initiator's payloads, and returns the (decrypted) transport message the initiator sent // Note that the received verifies if the received payloadV2 has the expected messageNametag set @@ -236,13 +248,14 @@ export class WakuPairing { const initiatorCommittedStaticKey = new Uint8Array(hsStep.transportMessage); + const confirmationPromise = this.isAuthCodeConfirmed(); + await delay(100); this.eventEmitter.emit("authCodeGenerated", this.handshake.genAuthcode()); - - const confirmed = await this.isAuthCodeConfirmed(); + console.log("Waiting for authcode confirmation..."); + const confirmed = await confirmationPromise; if (!confirmed) { throw new Error("authcode is not confirmed"); } - // 2nd step // <- sB, eAsB {r} // Receiver writes and returns a payload