feat: Switch between QR or phone number pairing method (#3180)
* fix(webpack-exodus): Added the new patch * fix(webpack-exodus): Fixed v2.3000.x and v2.24 * chore(webpack-exodus): eslint * fix(webpack-exodus): Fixed Store * fix(webpack-exodus): slight store fix * chore(webpack-exodus): fix example so that I don't crash on every load * chore: eslint fix * fix(webpack-exodus): prevent confusion with build systems * fix(webpack-exodus): Add proper groups module * fix(webpack-exodus): Fix order queries * fix(webpack-exodus): Bad export name * feat(webpack-exodus): Re-injection, No more selectors, Pairing Code auth * fix(webpack-exodus): Eslint and better login/logout handling * fix(webpack-exodus): 2.24 compatibility * revert testing options * chore(webpack-exodus): ESLint * chore(webpack-exodus): final eslint tweak (did not commit with last commit for some reason) * style: fix broken link in readme file * fix(webpack-exodus): Fix forwarding messages * fix(webpack-exodus): finish forwarding function * Making the ESLint god happy * Fix window.Store.ProfilePic.profilePicFind is not a function error (#3001) * Change window.Store.ProfilePic.profilePicFind to window.Store.ProfilePic.requestProfilePicFromServer * Prevent breaking v2.2x * refactor: make it more readable --------- Co-authored-by: alechkos <93551621+alechkos@users.noreply.github.com> * Sanitize, improves and fixes * make ESList god happy * fix getInviteCode for group (#3007) (#3029) * fix getInviteCode for group (#3007) * move changes to proper getInviteCode method. * style fix * refactor: add try-catch in a case the user is not a group admin * refactor: handle promise properly --------- Co-authored-by: Sven Neumann <s.neumann@websix.de> Co-authored-by: alechkos <93551621+alechkos@users.noreply.github.com> * fixes * Update LocalWebCache.js * fix delete on 2.3000 (#3048) * fix delete on 2.3000 * fix compareWwebVersions * fix: use proper comparison operator --------- Co-authored-by: alechkos <93551621+alechkos@users.noreply.github.com> * Implement bot invoking capabilities (#3009) * Implement bot invoking capabilities * Update index.d.ts * Eslint * Webpack exodus fix message_reaction event (#3099) * exposed WAWebAddonReactionTableMode * capture reaction using WAWebAddonReactionTableMode * move compareWwebVersions and check version before trying to expose new store * message_reaction on example.js (#3102) * handle message_reaction event on example.js * log wweb version on ready * fix reactions on pvt chats (#3104) * New group function * new group settings * Update Client.js * Switch pairing method between QR and phone number * Remove existing pairing code interval * Modify example.js * Update docs * Small improvements in inject function * Fix ESLint * example.js correction * docs: fix docs for 'requestPairingCode' method Co-authored-by: Leandro Matilla <30844484+wis-dev@users.noreply.github.com> * Update Utils.js getChatModel because Meta chat object affected Group Chats * Ajust to set isGroup as false as default * Remove the need for custom interval * Fix typo * Fix intermittent response bug #9864 Co-authored-by: Mob Code 100 <66469454+MobCode100@users.noreply.github.com> * fix: eslint fix * Revert "Remove the need for custom interval" This reverts commit c5d5e5626684742cadbf58f28739c1c2c9dcc582. * Add wait for PairingCodeLinkUtils on requestPairingCode * Remove unused vars WhatsWebStaticURL Co-authored-by: Mob Code 100 <66469454+MobCode100@users.noreply.github.com> * style: format code --------- Co-authored-by: Rajeh Taher <rajeh@reforward.dev> Co-authored-by: alechkos <93551621+alechkos@users.noreply.github.com> Co-authored-by: tuyuribr <45042245+tuyuribr@users.noreply.github.com> Co-authored-by: Seow Zhen Jun <56989187+seowzhenjun0126@users.noreply.github.com> Co-authored-by: Sven <sven2neumann@gmail.com> Co-authored-by: Sven Neumann <s.neumann@websix.de> Co-authored-by: Jorge Rocha Gualtieri <jorge@jrg.com.br> Co-authored-by: Mateus Mercer <accounts@matbm.net> Co-authored-by: Leandro Matilla <30844484+wis-dev@users.noreply.github.com> Co-authored-by: BenyFilho <168232825+BenyFilho@users.noreply.github.com> Co-authored-by: Shir Serlui <70711723+shirser121@users.noreply.github.com>
This commit is contained in:
parent
f9db14d185
commit
b5adf47664
4 changed files with 103 additions and 50 deletions
105
src/Client.js
105
src/Client.js
|
|
@ -96,8 +96,8 @@ class Client extends EventEmitter {
|
|||
*/
|
||||
async inject() {
|
||||
await this.pupPage.waitForFunction('window.Debug?.VERSION != undefined', {timeout: this.options.authTimeoutMs});
|
||||
|
||||
await this.setDeviceName(this.options.deviceName, this.options.browserName);
|
||||
const pairWithPhoneNumber = this.options.pairWithPhoneNumber;
|
||||
const version = await this.getWWebVersion();
|
||||
const isCometOrAbove = parseInt(version.split('.')?.[1]) >= 3000;
|
||||
|
||||
|
|
@ -143,41 +143,55 @@ class Client extends EventEmitter {
|
|||
return;
|
||||
}
|
||||
|
||||
// Register qr events
|
||||
let qrRetries = 0;
|
||||
await exposeFunctionIfAbsent(this.pupPage, 'onQRChangedEvent', async (qr) => {
|
||||
/**
|
||||
* Emitted when a QR code is received
|
||||
* @event Client#qr
|
||||
* @param {string} qr QR Code
|
||||
*/
|
||||
this.emit(Events.QR_RECEIVED, qr);
|
||||
if (this.options.qrMaxRetries > 0) {
|
||||
qrRetries++;
|
||||
if (qrRetries > this.options.qrMaxRetries) {
|
||||
this.emit(Events.DISCONNECTED, 'Max qrcode retries reached');
|
||||
await this.destroy();
|
||||
// Register qr/code events
|
||||
if (pairWithPhoneNumber.phoneNumber) {
|
||||
await exposeFunctionIfAbsent(this.pupPage, 'onCodeReceivedEvent', async (code) => {
|
||||
/**
|
||||
* Emitted when a pairing code is received
|
||||
* @event Client#code
|
||||
* @param {string} code Code
|
||||
* @returns {string} Code that was just received
|
||||
*/
|
||||
this.emit(Events.CODE_RECEIVED, code);
|
||||
return code;
|
||||
});
|
||||
this.requestPairingCode(pairWithPhoneNumber.phoneNumber, pairWithPhoneNumber.showNotification, pairWithPhoneNumber.intervalMs);
|
||||
} else {
|
||||
let qrRetries = 0;
|
||||
await exposeFunctionIfAbsent(this.pupPage, 'onQRChangedEvent', async (qr) => {
|
||||
/**
|
||||
* Emitted when a QR code is received
|
||||
* @event Client#qr
|
||||
* @param {string} qr QR Code
|
||||
*/
|
||||
this.emit(Events.QR_RECEIVED, qr);
|
||||
if (this.options.qrMaxRetries > 0) {
|
||||
qrRetries++;
|
||||
if (qrRetries > this.options.qrMaxRetries) {
|
||||
this.emit(Events.DISCONNECTED, 'Max qrcode retries reached');
|
||||
await this.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
await this.pupPage.evaluate(async () => {
|
||||
const registrationInfo = await window.AuthStore.RegistrationUtils.waSignalStore.getRegistrationInfo();
|
||||
const noiseKeyPair = await window.AuthStore.RegistrationUtils.waNoiseInfo.get();
|
||||
const staticKeyB64 = window.AuthStore.Base64Tools.encodeB64(noiseKeyPair.staticKeyPair.pubKey);
|
||||
const identityKeyB64 = window.AuthStore.Base64Tools.encodeB64(registrationInfo.identityKeyPair.pubKey);
|
||||
const advSecretKey = await window.AuthStore.RegistrationUtils.getADVSecretKey();
|
||||
const platform = window.AuthStore.RegistrationUtils.DEVICE_PLATFORM;
|
||||
const getQR = (ref) => ref + ',' + staticKeyB64 + ',' + identityKeyB64 + ',' + advSecretKey + ',' + platform;
|
||||
|
||||
window.onQRChangedEvent(getQR(window.AuthStore.Conn.ref)); // initial qr
|
||||
window.AuthStore.Conn.on('change:ref', (_, ref) => { window.onQRChangedEvent(getQR(ref)); }); // future QR changes
|
||||
});
|
||||
await this.pupPage.evaluate(async () => {
|
||||
const registrationInfo = await window.AuthStore.RegistrationUtils.waSignalStore.getRegistrationInfo();
|
||||
const noiseKeyPair = await window.AuthStore.RegistrationUtils.waNoiseInfo.get();
|
||||
const staticKeyB64 = window.AuthStore.Base64Tools.encodeB64(noiseKeyPair.staticKeyPair.pubKey);
|
||||
const identityKeyB64 = window.AuthStore.Base64Tools.encodeB64(registrationInfo.identityKeyPair.pubKey);
|
||||
const advSecretKey = await window.AuthStore.RegistrationUtils.getADVSecretKey();
|
||||
const platform = window.AuthStore.RegistrationUtils.DEVICE_PLATFORM;
|
||||
const getQR = (ref) => ref + ',' + staticKeyB64 + ',' + identityKeyB64 + ',' + advSecretKey + ',' + platform;
|
||||
|
||||
window.onQRChangedEvent(getQR(window.AuthStore.Conn.ref)); // initial qr
|
||||
window.AuthStore.Conn.on('change:ref', (_, ref) => { window.onQRChangedEvent(getQR(ref)); }); // future QR changes
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await exposeFunctionIfAbsent(this.pupPage, 'onAuthAppStateChangedEvent', async (state) => {
|
||||
if (state == 'UNPAIRED_IDLE') {
|
||||
if (state == 'UNPAIRED_IDLE' && !pairWithPhoneNumber.phoneNumber) {
|
||||
// refresh qr code
|
||||
window.Store.Cmd.refreshQR();
|
||||
}
|
||||
|
|
@ -346,15 +360,32 @@ class Client extends EventEmitter {
|
|||
/**
|
||||
* Request authentication via pairing code instead of QR code
|
||||
* @param {string} phoneNumber - Phone number in international, symbol-free format (e.g. 12025550108 for US, 551155501234 for Brazil)
|
||||
* @param {boolean} showNotification - Show notification to pair on phone number
|
||||
* @param {boolean} [showNotification = true] - Show notification to pair on phone number
|
||||
* @param {number} [intervalMs = 180000] - The interval in milliseconds on how frequent to generate pairing code (WhatsApp default to 3 minutes)
|
||||
* @returns {Promise<string>} - Returns a pairing code in format "ABCDEFGH"
|
||||
*/
|
||||
async requestPairingCode(phoneNumber, showNotification = true) {
|
||||
return await this.pupPage.evaluate(async (phoneNumber, showNotification) => {
|
||||
window.AuthStore.PairingCodeLinkUtils.setPairingType('ALT_DEVICE_LINKING');
|
||||
await window.AuthStore.PairingCodeLinkUtils.initializeAltDeviceLinking();
|
||||
return window.AuthStore.PairingCodeLinkUtils.startAltLinkingFlow(phoneNumber, showNotification);
|
||||
}, phoneNumber, showNotification);
|
||||
async requestPairingCode(phoneNumber, showNotification = true, intervalMs = 180000) {
|
||||
return await this.pupPage.evaluate(async (phoneNumber, showNotification, intervalMs) => {
|
||||
const getCode = async () => {
|
||||
while (!window.AuthStore.PairingCodeLinkUtils) {
|
||||
await new Promise(resolve => setTimeout(resolve, 250));
|
||||
}
|
||||
window.AuthStore.PairingCodeLinkUtils.setPairingType('ALT_DEVICE_LINKING');
|
||||
await window.AuthStore.PairingCodeLinkUtils.initializeAltDeviceLinking();
|
||||
return window.AuthStore.PairingCodeLinkUtils.startAltLinkingFlow(phoneNumber, showNotification);
|
||||
};
|
||||
if (window.codeInterval) {
|
||||
clearInterval(window.codeInterval); // remove existing interval
|
||||
}
|
||||
window.codeInterval = setInterval(async () => {
|
||||
if (window.AuthStore.AppState.state != 'UNPAIRED' && window.AuthStore.AppState.state != 'UNPAIRED_IDLE') {
|
||||
clearInterval(window.codeInterval);
|
||||
return;
|
||||
}
|
||||
window.onCodeReceivedEvent(await getCode());
|
||||
}, intervalMs);
|
||||
return window.onCodeReceivedEvent(await getCode());
|
||||
}, phoneNumber, showNotification, intervalMs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue