feat: add cancelPairingCode() and requestPairingCode() on QR clients (#22449)

* feat: add cancelPairingCode() and allow requestPairingCode()

- requestPairingCode() now exposes onCodeReceivedEvent if needed,
  so it works on clients initialized in QR mode
- Add cancelPairingCode() method to stop pairing and return to QR
- Update TypeScript definitions

* fix(auth): dynamic ADV key in getQR + structural cancelPairingCode

the getQR closure captured advSecretKey once during initialize(), but
requestpairingcode/cancelPairingCode changes the key in IndexedDB.
the stale closure key caused QR scans to fail with HMAC validation error.

fix: read key dynamically via WAWebUserPrefsMultiDevice.getADVSecretKey()
(synchronous in-memory cache) on every getQR call, matching how WhatsApp
web's internal QR component works.

cancelpairingcode now mirrors WhatsApp Web's resetLinkDeviceState:
refreshqr() restarts WebSocket for fresh refs, then
initializeqrlinking() generates a new key. QR emission happens
automatically via the existing change:ref listener.

---------

Co-authored-by: BenyFilho <168232825+BenyFilho@users.noreply.github.com>
This commit is contained in:
Adi1231234 2026-03-24 15:01:31 +02:00 • committed by GitHub
commit 3e810b6913
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 4 deletions

View file

@ -255,8 +255,6 @@ class Client extends EventEmitter {
window.AuthStore.Base64Tools.encodeB64(
registrationInfo.identityKeyPair.pubKey,
);
const advSecretKey =
await window.AuthStore.RegistrationUtils.getADVSecretKey();
const platform =
window.AuthStore.RegistrationUtils.DEVICE_PLATFORM;
const getQR = (ref) =>
@ -266,10 +264,11 @@ class Client extends EventEmitter {
',' +
identityKeyB64 +
',' +
advSecretKey +
window
.require('WAWebUserPrefsMultiDevice')
.getADVSecretKey() +
',' +
platform;
window.onQRChangedEvent(getQR(window.AuthStore.Conn.ref)); // initial qr
window.AuthStore.Conn.on('change:ref', (_, ref) => {
window.onQRChangedEvent(getQR(ref));
@ -516,6 +515,14 @@ class Client extends EventEmitter {
showNotification = true,
intervalMs = 180000,
) {
await exposeFunctionIfAbsent(
this.pupPage,
'onCodeReceivedEvent',
async (code) => {
this.emit(Events.CODE_RECEIVED, code);
return code;
},
);
return await this.pupPage.evaluate(
async (phoneNumber, showNotification, intervalMs) => {
const getCode = async () => {
@ -553,6 +560,22 @@ class Client extends EventEmitter {
);
}
/**
* Cancels an active pairing code session and returns to QR code mode
*/
async cancelPairingCode() {
await this.pupPage.evaluate(async () => {
if (window.codeInterval) {
clearInterval(window.codeInterval);
window.codeInterval = undefined;
}
window.require('WAWebLaunchSocketUtils').refreshQR();
await window
.require('WAWebAltDeviceLinkingApi')
.initializeQRLinking();
});
}
/**
* Attach event listeners to WA Web
* Private function