general: tree-shaking pre-MD and old comet versions (#5675)
Co-authored-by: BenyFilho <168232825+BenyFilho@users.noreply.github.com> Co-authored-by: tuyuribr <45042245+tuyuribr@users.noreply.github.com>
This commit is contained in:
parent
073cf3185d
commit
9b1eb76b2b
10 changed files with 70 additions and 469 deletions
27
index.d.ts
vendored
27
index.d.ts
vendored
|
|
@ -323,10 +323,6 @@ declare namespace WAWebJS {
|
||||||
|
|
||||||
/** Emitted when authentication is successful */
|
/** Emitted when authentication is successful */
|
||||||
on(event: 'authenticated', listener: (
|
on(event: 'authenticated', listener: (
|
||||||
/**
|
|
||||||
* Object containing session information, when using LegacySessionAuth. Can be used to restore the session
|
|
||||||
*/
|
|
||||||
session?: ClientSession
|
|
||||||
) => void): this
|
) => void): this
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -567,7 +563,7 @@ declare namespace WAWebJS {
|
||||||
evalOnNewDoc?: Function,
|
evalOnNewDoc?: Function,
|
||||||
/** Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/ */
|
/** Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/ */
|
||||||
puppeteer?: puppeteer.PuppeteerNodeLaunchOptions & puppeteer.ConnectOptions
|
puppeteer?: puppeteer.PuppeteerNodeLaunchOptions & puppeteer.ConnectOptions
|
||||||
/** Determines how to save and restore sessions. Will use LegacySessionAuth if options.session is set. Otherwise, NoAuth will be used. */
|
/** Determines how to save and restore sessions. Otherwise, NoAuth will be used. */
|
||||||
authStrategy?: AuthStrategy,
|
authStrategy?: AuthStrategy,
|
||||||
/** The version of WhatsApp Web to use. Use options.webVersionCache to configure how the version is retrieved. */
|
/** The version of WhatsApp Web to use. Use options.webVersionCache to configure how the version is retrieved. */
|
||||||
webVersion?: string,
|
webVersion?: string,
|
||||||
|
|
@ -575,15 +571,7 @@ declare namespace WAWebJS {
|
||||||
webVersionCache?: WebCacheOptions,
|
webVersionCache?: WebCacheOptions,
|
||||||
/** How many times should the qrcode be refreshed before giving up
|
/** How many times should the qrcode be refreshed before giving up
|
||||||
* @default 0 (disabled) */
|
* @default 0 (disabled) */
|
||||||
qrMaxRetries?: number,
|
qrMaxRetries?: number
|
||||||
/**
|
|
||||||
* @deprecated This option should be set directly on the LegacySessionAuth
|
|
||||||
*/
|
|
||||||
restartOnAuthFail?: boolean
|
|
||||||
/**
|
|
||||||
* @deprecated Only here for backwards-compatibility. You should move to using LocalAuth, or set the authStrategy to LegacySessionAuth explicitly.
|
|
||||||
*/
|
|
||||||
session?: ClientSession
|
|
||||||
/** If another whatsapp web session is detected (another browser), take over the session in the current browser
|
/** If another whatsapp web session is detected (another browser), take over the session in the current browser
|
||||||
* @default false */
|
* @default false */
|
||||||
takeoverOnConflict?: boolean,
|
takeoverOnConflict?: boolean,
|
||||||
|
|
@ -700,17 +688,6 @@ declare namespace WAWebJS {
|
||||||
extract: (options: { session: string, path: string }) => Promise<any> | any,
|
extract: (options: { session: string, path: string }) => Promise<any> | any,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Legacy session auth strategy
|
|
||||||
* Not compatible with multi-device accounts.
|
|
||||||
*/
|
|
||||||
export class LegacySessionAuth extends AuthStrategy {
|
|
||||||
constructor(options?: {
|
|
||||||
session?: ClientSession,
|
|
||||||
restartOnAuthFail?: boolean,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a WhatsApp client session
|
* Represents a WhatsApp client session
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@
|
||||||
},
|
},
|
||||||
"homepage": "https://wwebjs.dev/",
|
"homepage": "https://wwebjs.dev/",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pedroslopez/moduleraid": "^5.0.2",
|
|
||||||
"fluent-ffmpeg": "2.1.3",
|
"fluent-ffmpeg": "2.1.3",
|
||||||
"mime": "^3.0.0",
|
"mime": "^3.0.0",
|
||||||
"node-fetch": "^2.6.9",
|
"node-fetch": "^2.6.9",
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,12 @@
|
||||||
|
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const puppeteer = require('puppeteer');
|
const puppeteer = require('puppeteer');
|
||||||
const moduleRaid = require('@pedroslopez/moduleraid/moduleraid');
|
|
||||||
|
|
||||||
const Util = require('./util/Util');
|
const Util = require('./util/Util');
|
||||||
const InterfaceController = require('./util/InterfaceController');
|
const InterfaceController = require('./util/InterfaceController');
|
||||||
const { WhatsWebURL, DefaultOptions, Events, WAState, MessageTypes } = require('./util/Constants');
|
const { WhatsWebURL, DefaultOptions, Events, WAState, MessageTypes } = require('./util/Constants');
|
||||||
const { ExposeAuthStore } = require('./util/Injected/AuthStore/AuthStore');
|
const { ExposeAuthStore } = require('./util/Injected/AuthStore/AuthStore');
|
||||||
const { ExposeStore } = require('./util/Injected/Store');
|
const { ExposeStore } = require('./util/Injected/Store');
|
||||||
const { ExposeLegacyAuthStore } = require('./util/Injected/AuthStore/LegacyAuthStore');
|
|
||||||
const { ExposeLegacyStore } = require('./util/Injected/LegacyStore');
|
|
||||||
const { LoadUtils } = require('./util/Injected/Utils');
|
const { LoadUtils } = require('./util/Injected/Utils');
|
||||||
const ChatFactory = require('./factories/ChatFactory');
|
const ChatFactory = require('./factories/ChatFactory');
|
||||||
const ContactFactory = require('./factories/ContactFactory');
|
const ContactFactory = require('./factories/ContactFactory');
|
||||||
|
|
@ -23,15 +20,13 @@ const {exposeFunctionIfAbsent} = require('./util/Puppeteer');
|
||||||
* Starting point for interacting with the WhatsApp Web API
|
* Starting point for interacting with the WhatsApp Web API
|
||||||
* @extends {EventEmitter}
|
* @extends {EventEmitter}
|
||||||
* @param {object} options - Client options
|
* @param {object} options - Client options
|
||||||
* @param {AuthStrategy} options.authStrategy - Determines how to save and restore sessions. Will use LegacySessionAuth if options.session is set. Otherwise, NoAuth will be used.
|
* @param {AuthStrategy} options.authStrategy - Determines how to save and restore sessions. Otherwise, NoAuth will be used.
|
||||||
* @param {string} options.webVersion - The version of WhatsApp Web to use. Use options.webVersionCache to configure how the version is retrieved.
|
* @param {string} options.webVersion - The version of WhatsApp Web to use. Use options.webVersionCache to configure how the version is retrieved.
|
||||||
* @param {object} options.webVersionCache - Determines how to retrieve the WhatsApp Web version. Defaults to a local cache (LocalWebCache) that falls back to latest if the requested version is not found.
|
* @param {object} options.webVersionCache - Determines how to retrieve the WhatsApp Web version. Defaults to a local cache (LocalWebCache) that falls back to latest if the requested version is not found.
|
||||||
* @param {number} options.authTimeoutMs - Timeout for authentication selector in puppeteer
|
* @param {number} options.authTimeoutMs - Timeout for authentication selector in puppeteer
|
||||||
* @param {function} options.evalOnNewDoc - function to eval on new doc
|
* @param {function} options.evalOnNewDoc - function to eval on new doc
|
||||||
* @param {object} options.puppeteer - Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/
|
* @param {object} options.puppeteer - Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/
|
||||||
* @param {number} options.qrMaxRetries - How many times should the qrcode be refreshed before giving up
|
* @param {number} options.qrMaxRetries - How many times should the qrcode be refreshed before giving up
|
||||||
* @param {string} options.restartOnAuthFail - @deprecated This option should be set directly on the LegacySessionAuth.
|
|
||||||
* @param {object} options.session - @deprecated Only here for backwards-compatibility. You should move to using LocalAuth, or set the authStrategy to LegacySessionAuth explicitly.
|
|
||||||
* @param {number} options.takeoverOnConflict - If another whatsapp web session is detected (another browser), take over the session in the current browser
|
* @param {number} options.takeoverOnConflict - If another whatsapp web session is detected (another browser), take over the session in the current browser
|
||||||
* @param {number} options.takeoverTimeoutMs - How much time to wait before taking over the session
|
* @param {number} options.takeoverTimeoutMs - How much time to wait before taking over the session
|
||||||
* @param {string} options.userAgent - User agent to use in puppeteer
|
* @param {string} options.userAgent - User agent to use in puppeteer
|
||||||
|
|
@ -113,13 +108,8 @@ class Client extends EventEmitter {
|
||||||
await this.setDeviceName(this.options.deviceName, this.options.browserName);
|
await this.setDeviceName(this.options.deviceName, this.options.browserName);
|
||||||
const pairWithPhoneNumber = this.options.pairWithPhoneNumber;
|
const pairWithPhoneNumber = this.options.pairWithPhoneNumber;
|
||||||
const version = await this.getWWebVersion();
|
const version = await this.getWWebVersion();
|
||||||
const isCometOrAbove = parseInt(version.split('.')?.[1]) >= 3000;
|
|
||||||
|
|
||||||
if (isCometOrAbove) {
|
|
||||||
await this.pupPage.evaluate(ExposeAuthStore);
|
await this.pupPage.evaluate(ExposeAuthStore);
|
||||||
} else {
|
|
||||||
await this.pupPage.evaluate(ExposeLegacyAuthStore, moduleRaid.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
const needAuthentication = await this.pupPage.evaluate(async () => {
|
const needAuthentication = await this.pupPage.evaluate(async () => {
|
||||||
let state = window.AuthStore.AppState.state;
|
let state = window.AuthStore.AppState.state;
|
||||||
|
|
@ -231,14 +221,8 @@ class Client extends EventEmitter {
|
||||||
await webCache.persist(this.currentIndexHtml, version);
|
await webCache.persist(this.currentIndexHtml, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCometOrAbove) {
|
|
||||||
await this.pupPage.evaluate(ExposeStore);
|
await this.pupPage.evaluate(ExposeStore);
|
||||||
} else {
|
|
||||||
// make sure all modules are ready before injection
|
|
||||||
// 2 second delay after authentication makes sense and does not need to be made dyanmic or removed
|
|
||||||
await new Promise(r => setTimeout(r, 2000));
|
|
||||||
await this.pupPage.evaluate(ExposeLegacyStore);
|
|
||||||
}
|
|
||||||
let start = Date.now();
|
let start = Date.now();
|
||||||
let res = false;
|
let res = false;
|
||||||
while(start > (Date.now() - 30000)){
|
while(start > (Date.now() - 30000)){
|
||||||
|
|
@ -354,17 +338,14 @@ class Client extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ocVersion (isOfficialClient patch)
|
// ocVersion (isOfficialClient patch)
|
||||||
// remove after 2.3000.x hard release
|
|
||||||
await page.evaluateOnNewDocument(() => {
|
await page.evaluateOnNewDocument(() => {
|
||||||
const originalError = Error;
|
window.originalError = Error;
|
||||||
window.originalError = originalError;
|
|
||||||
//eslint-disable-next-line no-global-assign
|
//eslint-disable-next-line no-global-assign
|
||||||
Error = function (message) {
|
Error = ((message) => {
|
||||||
const error = new originalError(message);
|
const error = new window.originalError(message);
|
||||||
const originalStack = error.stack;
|
error.stack = error.stack + '\n at https://web.whatsapp.com/vendors~lazy_loaded_low_priority_components.05e98054dbd60f980427.js:2:44';
|
||||||
if (error.stack.includes('moduleRaid')) error.stack = originalStack + '\n at https://web.whatsapp.com/vendors~lazy_loaded_low_priority_components.05e98054dbd60f980427.js:2:44';
|
|
||||||
return error;
|
return error;
|
||||||
};
|
}).bind(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
await page.goto(WhatsWebURL, {
|
await page.goto(WhatsWebURL, {
|
||||||
|
|
@ -778,7 +759,6 @@ class Client extends EventEmitter {
|
||||||
});
|
});
|
||||||
window.Store.Chat.on('change:unreadCount', (chat) => {window.onChatUnreadCountEvent(chat);});
|
window.Store.Chat.on('change:unreadCount', (chat) => {window.onChatUnreadCountEvent(chat);});
|
||||||
|
|
||||||
if (window.compareWwebVersions(window.Debug.VERSION, '>=', '2.3000.1014111620')) {
|
|
||||||
const module = window.Store.AddonReactionTable;
|
const module = window.Store.AddonReactionTable;
|
||||||
const ogMethod = module.bulkUpsert;
|
const ogMethod = module.bulkUpsert;
|
||||||
module.bulkUpsert = ((...args) => {
|
module.bulkUpsert = ((...args) => {
|
||||||
|
|
@ -827,21 +807,6 @@ class Client extends EventEmitter {
|
||||||
|
|
||||||
return ogPollVoteMethod.apply(pollVoteModule, args);
|
return ogPollVoteMethod.apply(pollVoteModule, args);
|
||||||
}).bind(pollVoteModule);
|
}).bind(pollVoteModule);
|
||||||
} else {
|
|
||||||
const module = window.Store.createOrUpdateReactionsModule;
|
|
||||||
const ogMethod = module.createOrUpdateReactions;
|
|
||||||
module.createOrUpdateReactions = ((...args) => {
|
|
||||||
window.onReaction(args[0].map(reaction => {
|
|
||||||
const msgKey = window.Store.MsgKey.fromString(reaction.msgKey);
|
|
||||||
const parentMsgKey = window.Store.MsgKey.fromString(reaction.parentMsgKey);
|
|
||||||
const timestamp = reaction.timestamp / 1000;
|
|
||||||
|
|
||||||
return {...reaction, msgKey, parentMsgKey, timestamp };
|
|
||||||
}));
|
|
||||||
|
|
||||||
return ogMethod(...args);
|
|
||||||
}).bind(module);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1564,9 +1529,7 @@ class Client extends EventEmitter {
|
||||||
const profilePic = await this.pupPage.evaluate(async contactId => {
|
const profilePic = await this.pupPage.evaluate(async contactId => {
|
||||||
try {
|
try {
|
||||||
const chatWid = window.Store.WidFactory.createWid(contactId);
|
const chatWid = window.Store.WidFactory.createWid(contactId);
|
||||||
return window.compareWwebVersions(window.Debug.VERSION, '<', '2.3000.0')
|
return await window.Store.ProfilePic.requestProfilePicFromServer(chatWid);
|
||||||
? await window.Store.ProfilePic.profilePicFind(chatWid)
|
|
||||||
: await window.Store.ProfilePic.requestProfilePicFromServer(chatWid);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if(err.name === 'ServerStatusCodeError') return undefined;
|
if(err.name === 'ServerStatusCodeError') return undefined;
|
||||||
throw err;
|
throw err;
|
||||||
|
|
|
||||||
|
|
@ -389,11 +389,8 @@ class GroupChat extends Chat {
|
||||||
*/
|
*/
|
||||||
async getInviteCode() {
|
async getInviteCode() {
|
||||||
const codeRes = await this.client.pupPage.evaluate(async chatId => {
|
const codeRes = await this.client.pupPage.evaluate(async chatId => {
|
||||||
const chatWid = window.Store.WidFactory.createWid(chatId);
|
|
||||||
try {
|
try {
|
||||||
return window.compareWwebVersions(window.Debug.VERSION, '>=', '2.3000.1020730154')
|
return await window.Store.GroupInvite.fetchMexGroupInviteCode(chatId);
|
||||||
? await window.Store.GroupInvite.fetchMexGroupInviteCode(chatId)
|
|
||||||
: await window.Store.GroupInvite.queryGroupInviteCode(chatWid, true);
|
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
if(err.name === 'ServerStatusCodeError') return undefined;
|
if(err.name === 'ServerStatusCodeError') return undefined;
|
||||||
|
|
|
||||||
|
|
@ -515,14 +515,10 @@ class Message extends Base {
|
||||||
window.Store.MsgActionChecks.canSenderRevokeMsg(msg) || window.Store.MsgActionChecks.canAdminRevokeMsg(msg);
|
window.Store.MsgActionChecks.canSenderRevokeMsg(msg) || window.Store.MsgActionChecks.canAdminRevokeMsg(msg);
|
||||||
|
|
||||||
if (everyone && canRevoke) {
|
if (everyone && canRevoke) {
|
||||||
return window.compareWwebVersions(window.Debug.VERSION, '>=', '2.3000.0')
|
return window.Store.Cmd.sendRevokeMsgs(chat, { list: [msg], type: 'message' }, { clearMedia: clearMedia });
|
||||||
? window.Store.Cmd.sendRevokeMsgs(chat, { list: [msg], type: 'message' }, { clearMedia: clearMedia })
|
|
||||||
: window.Store.Cmd.sendRevokeMsgs(chat, [msg], { clearMedia: true, type: msg.id.fromMe ? 'Sender' : 'Admin' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return window.compareWwebVersions(window.Debug.VERSION, '>=', '2.3000.0')
|
return window.Store.Cmd.sendDeleteMsgs(chat, { list: [msg], type: 'message' }, clearMedia);
|
||||||
? window.Store.Cmd.sendDeleteMsgs(chat, { list: [msg], type: 'message' }, clearMedia)
|
|
||||||
: window.Store.Cmd.sendDeleteMsgs(chat, [msg], clearMedia);
|
|
||||||
}, this.id._serialized, everyone, clearMedia);
|
}, this.id._serialized, everyone, clearMedia);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ exports.DefaultOptions = {
|
||||||
headless: true,
|
headless: true,
|
||||||
defaultViewport: null
|
defaultViewport: null
|
||||||
},
|
},
|
||||||
webVersion: '2.3000.1017054665',
|
webVersion: '2.3000.1030947950',
|
||||||
webVersionCache: {
|
webVersionCache: {
|
||||||
type: 'local',
|
type: 'local',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
//TODO: To be removed by version 2.3000.x hard release
|
|
||||||
|
|
||||||
exports.ExposeLegacyAuthStore = (moduleRaidStr) => {
|
|
||||||
eval('var moduleRaid = ' + moduleRaidStr);
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
window.mR = moduleRaid();
|
|
||||||
window.AuthStore = {};
|
|
||||||
window.AuthStore.AppState = window.mR.findModule('Socket')[0].Socket;
|
|
||||||
window.AuthStore.Cmd = window.mR.findModule('Cmd')[0].Cmd;
|
|
||||||
window.AuthStore.Conn = window.mR.findModule('Conn')[0].Conn;
|
|
||||||
window.AuthStore.OfflineMessageHandler = window.mR.findModule('OfflineMessageHandler')[0].OfflineMessageHandler;
|
|
||||||
window.AuthStore.PairingCodeLinkUtils = window.mR.findModule('initializeAltDeviceLinking')[0];
|
|
||||||
window.AuthStore.Base64Tools = window.mR.findModule('encodeB64')[0];
|
|
||||||
window.AuthStore.RegistrationUtils = {
|
|
||||||
...window.mR.findModule('getCompanionWebClientFromBrowser')[0],
|
|
||||||
...window.mR.findModule('verifyKeyIndexListAccountSignature')[0],
|
|
||||||
...window.mR.findModule('waNoiseInfo')[0],
|
|
||||||
...window.mR.findModule('waSignalStore')[0],
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
//TODO: To be removed by version 2.3000.x hard release
|
|
||||||
|
|
||||||
// Exposes the internal Store to the WhatsApp Web client
|
|
||||||
exports.ExposeLegacyStore = () => {
|
|
||||||
window.Store = Object.assign({}, window.mR.findModule(m => m.default && m.default.Chat)[0].default);
|
|
||||||
window.Store.AppState = window.mR.findModule('Socket')[0].Socket;
|
|
||||||
window.Store.Conn = window.mR.findModule('Conn')[0].Conn;
|
|
||||||
window.Store.BlockContact = window.mR.findModule('blockContact')[0];
|
|
||||||
window.Store.Call = window.mR.findModule((module) => module.default && module.default.Call)[0].default.Call;
|
|
||||||
window.Store.Cmd = window.mR.findModule('Cmd')[0].Cmd;
|
|
||||||
window.Store.CryptoLib = window.mR.findModule('decryptE2EMedia')[0];
|
|
||||||
window.Store.DownloadManager = window.mR.findModule('downloadManager')[0].downloadManager;
|
|
||||||
window.Store.GroupMetadata = window.mR.findModule('GroupMetadata')[0].default.GroupMetadata;
|
|
||||||
window.Store.GroupQueryAndUpdate = window.mR.findModule('queryAndUpdateGroupMetadataById')[0].queryAndUpdateGroupMetadataById;
|
|
||||||
window.Store.Label = window.mR.findModule('LabelCollection')[0].LabelCollection;
|
|
||||||
window.Store.MediaPrep = window.mR.findModule('prepRawMedia')[0];
|
|
||||||
window.Store.MediaObject = window.mR.findModule('getOrCreateMediaObject')[0];
|
|
||||||
window.Store.NumberInfo = window.mR.findModule('formattedPhoneNumber')[0];
|
|
||||||
window.Store.MediaTypes = window.mR.findModule('msgToMediaType')[0];
|
|
||||||
window.Store.MediaUpload = window.mR.findModule('uploadMedia')[0];
|
|
||||||
window.Store.MsgKey = window.mR.findModule((module) => module.default && module.default.fromString)[0].default;
|
|
||||||
window.Store.OpaqueData = window.mR.findModule(module => module.default && module.default.createFromData)[0].default;
|
|
||||||
window.Store.QueryProduct = window.mR.findModule('queryProduct')[0];
|
|
||||||
window.Store.QueryOrder = window.mR.findModule('queryOrder')[0];
|
|
||||||
window.Store.SendClear = window.mR.findModule('sendClear')[0];
|
|
||||||
window.Store.SendDelete = window.mR.findModule('sendDelete')[0];
|
|
||||||
window.Store.SendMessage = window.mR.findModule('addAndSendMsgToChat')[0];
|
|
||||||
window.Store.EditMessage = window.mR.findModule('addAndSendMessageEdit')[0];
|
|
||||||
window.Store.SendSeen = window.mR.findModule('sendSeen')[0];
|
|
||||||
window.Store.User = window.mR.findModule('getMaybeMeUser')[0];
|
|
||||||
window.Store.ContactMethods = window.mR.findModule('getUserid')[0];
|
|
||||||
window.Store.UploadUtils = window.mR.findModule((module) => (module.default && module.default.encryptAndUpload) ? module.default : null)[0].default;
|
|
||||||
window.Store.UserConstructor = window.mR.findModule((module) => (module.default && module.default.prototype && module.default.prototype.isServer && module.default.prototype.isUser) ? module.default : null)[0].default;
|
|
||||||
window.Store.Validators = window.mR.findModule('findLinks')[0];
|
|
||||||
window.Store.VCard = window.mR.findModule('vcardFromContactModel')[0];
|
|
||||||
window.Store.WidFactory = window.mR.findModule('createWid')[0];
|
|
||||||
window.Store.ProfilePic = window.mR.findModule('profilePicResync')[0];
|
|
||||||
window.Store.PresenceUtils = window.mR.findModule('sendPresenceAvailable')[0];
|
|
||||||
window.Store.ChatState = window.mR.findModule('sendChatStateComposing')[0];
|
|
||||||
window.Store.findCommonGroups = window.mR.findModule('findCommonGroups')[0].findCommonGroups;
|
|
||||||
window.Store.StatusUtils = window.mR.findModule('setMyStatus')[0];
|
|
||||||
window.Store.ConversationMsgs = window.mR.findModule('loadEarlierMsgs')[0];
|
|
||||||
window.Store.sendReactionToMsg = window.mR.findModule('sendReactionToMsg')[0].sendReactionToMsg;
|
|
||||||
window.Store.createOrUpdateReactionsModule = window.mR.findModule('createOrUpdateReactions')[0];
|
|
||||||
window.Store.EphemeralFields = window.mR.findModule('getEphemeralFields')[0];
|
|
||||||
window.Store.MsgActionChecks = window.mR.findModule('canSenderRevokeMsg')[0];
|
|
||||||
window.Store.QuotedMsg = window.mR.findModule('getQuotedMsgObj')[0];
|
|
||||||
window.Store.LinkPreview = window.mR.findModule('getLinkPreview')[0];
|
|
||||||
window.Store.Socket = window.mR.findModule('deprecatedSendIq')[0];
|
|
||||||
window.Store.SocketWap = window.mR.findModule('wap')[0];
|
|
||||||
window.Store.SearchContext = window.mR.findModule('getSearchContext')[0].getSearchContext;
|
|
||||||
window.Store.DrawerManager = window.mR.findModule('DrawerManager')[0].DrawerManager;
|
|
||||||
window.Store.LidUtils = window.mR.findModule('getCurrentLid')[0];
|
|
||||||
window.Store.WidToJid = window.mR.findModule('widToUserJid')[0];
|
|
||||||
window.Store.JidToWid = window.mR.findModule('userJidToUserWid')[0];
|
|
||||||
window.Store.getMsgInfo = (window.mR.findModule('sendQueryMsgInfo')[0] || {}).sendQueryMsgInfo || window.mR.findModule('queryMsgInfo')[0].queryMsgInfo;
|
|
||||||
window.Store.pinUnpinMsg = window.mR.findModule('sendPinInChatMsg')[0].sendPinInChatMsg;
|
|
||||||
|
|
||||||
/* eslint-disable no-undef, no-cond-assign */
|
|
||||||
window.Store.QueryExist = ((m = window.mR.findModule('queryExists')[0]) ? m.queryExists : window.mR.findModule('queryExist')[0].queryWidExists);
|
|
||||||
window.Store.ReplyUtils = (m = window.mR.findModule('canReplyMsg')).length > 0 && m[0];
|
|
||||||
/* eslint-enable no-undef, no-cond-assign */
|
|
||||||
|
|
||||||
window.Store.Settings = {
|
|
||||||
...window.mR.findModule('ChatlistPanelState')[0],
|
|
||||||
setPushname: window.mR.findModule((m) => m.setPushname && !m.ChatlistPanelState)[0].setPushname
|
|
||||||
};
|
|
||||||
window.Store.StickerTools = {
|
|
||||||
...window.mR.findModule('toWebpSticker')[0],
|
|
||||||
...window.mR.findModule('addWebpMetadata')[0]
|
|
||||||
};
|
|
||||||
window.Store.GroupUtils = {
|
|
||||||
...window.mR.findModule('createGroup')[0],
|
|
||||||
...window.mR.findModule('setGroupDescription')[0],
|
|
||||||
...window.mR.findModule('sendExitGroup')[0],
|
|
||||||
...window.mR.findModule('sendSetPicture')[0]
|
|
||||||
};
|
|
||||||
window.Store.GroupParticipants = {
|
|
||||||
...window.mR.findModule('promoteParticipants')[0],
|
|
||||||
...window.mR.findModule('sendAddParticipantsRPC')[0]
|
|
||||||
};
|
|
||||||
window.Store.GroupInvite = {
|
|
||||||
...window.mR.findModule('resetGroupInviteCode')[0],
|
|
||||||
...window.mR.findModule('queryGroupInvite')[0]
|
|
||||||
};
|
|
||||||
window.Store.GroupInviteV4 = {
|
|
||||||
...window.mR.findModule('queryGroupInviteV4')[0],
|
|
||||||
...window.mR.findModule('sendGroupInviteMessage')[0]
|
|
||||||
};
|
|
||||||
window.Store.MembershipRequestUtils = {
|
|
||||||
...window.mR.findModule('getMembershipApprovalRequests')[0],
|
|
||||||
...window.mR.findModule('sendMembershipRequestsActionRPC')[0]
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!window.Store.Chat._find) {
|
|
||||||
window.Store.Chat._find = e => {
|
|
||||||
const target = window.Store.Chat.get(e);
|
|
||||||
return target ? Promise.resolve(target) : Promise.resolve({
|
|
||||||
id: e
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
if ((m = window.mR.findModule('ChatCollection')[0]) && m.ChatCollection && typeof m.ChatCollection.findImpl === 'undefined' && typeof m.ChatCollection._find !== 'undefined') m.ChatCollection.findImpl = m.ChatCollection._find;
|
|
||||||
|
|
||||||
const _isMDBackend = window.mR.findModule('isMDBackend');
|
|
||||||
if(_isMDBackend && _isMDBackend[0] && _isMDBackend[0].isMDBackend) {
|
|
||||||
window.Store.MDBackend = _isMDBackend[0].isMDBackend();
|
|
||||||
} else {
|
|
||||||
window.Store.MDBackend = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const _features = window.mR.findModule('FEATURE_CHANGE_EVENT')[0];
|
|
||||||
if(_features) {
|
|
||||||
window.Store.Features = _features.LegacyPhoneFeatures;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Target options object description
|
|
||||||
* @typedef {Object} TargetOptions
|
|
||||||
* @property {string|number} module The name or a key of the target module to search
|
|
||||||
* @property {number} index The index value of the target module
|
|
||||||
* @property {string} function The function name to get from a module
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to modify functions
|
|
||||||
* @param {TargetOptions} target Options specifying the target function to search for modifying
|
|
||||||
* @param {Function} callback Modified function
|
|
||||||
*/
|
|
||||||
window.injectToFunction = (target, callback) => {
|
|
||||||
const module = typeof target.module === 'string'
|
|
||||||
? window.mR.findModule(target.module)
|
|
||||||
: window.mR.modules[target.module];
|
|
||||||
const originalFunction = module[target.index][target.function];
|
|
||||||
const modifiedFunction = (...args) => callback(originalFunction, ...args);
|
|
||||||
module[target.index][target.function] = modifiedFunction;
|
|
||||||
};
|
|
||||||
|
|
||||||
window.injectToFunction({ module: 'mediaTypeFromProtobuf', index: 0, function: 'mediaTypeFromProtobuf' }, (func, ...args) => { const [proto] = args; return proto.locationMessage ? null : func(...args); });
|
|
||||||
|
|
||||||
window.injectToFunction({ module: 'typeAttributeFromProtobuf', index: 0, function: 'typeAttributeFromProtobuf' }, (func, ...args) => { const [proto] = args; return proto.locationMessage || proto.groupInviteMessage ? 'text' : func(...args); });
|
|
||||||
};
|
|
||||||
132
tests/client.js
132
tests/client.js
|
|
@ -8,14 +8,12 @@ const Contact = require('../src/structures/Contact');
|
||||||
const Message = require('../src/structures/Message');
|
const Message = require('../src/structures/Message');
|
||||||
const MessageMedia = require('../src/structures/MessageMedia');
|
const MessageMedia = require('../src/structures/MessageMedia');
|
||||||
const Location = require('../src/structures/Location');
|
const Location = require('../src/structures/Location');
|
||||||
const LegacySessionAuth = require('../src/authStrategies/LegacySessionAuth');
|
const { MessageTypes, DefaultOptions } = require('../src/util/Constants');
|
||||||
const { MessageTypes, WAState, DefaultOptions } = require('../src/util/Constants');
|
|
||||||
|
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
chai.use(chaiAsPromised);
|
chai.use(chaiAsPromised);
|
||||||
|
|
||||||
const remoteId = helper.remoteId;
|
const remoteId = helper.remoteId;
|
||||||
const isMD = helper.isMD();
|
|
||||||
|
|
||||||
describe('Client', function() {
|
describe('Client', function() {
|
||||||
describe('User Agent', function () {
|
describe('User Agent', function () {
|
||||||
|
|
@ -139,139 +137,11 @@ describe('Client', function() {
|
||||||
await client.initialize();
|
await client.initialize();
|
||||||
|
|
||||||
expect(authenticatedCallback.called).to.equal(true);
|
expect(authenticatedCallback.called).to.equal(true);
|
||||||
|
|
||||||
if(helper.isUsingLegacySession()) {
|
|
||||||
const newSession = authenticatedCallback.args[0][0];
|
|
||||||
expect(newSession).to.have.key([
|
|
||||||
'WABrowserId',
|
|
||||||
'WASecretBundle',
|
|
||||||
'WAToken1',
|
|
||||||
'WAToken2'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(readyCallback.called).to.equal(true);
|
expect(readyCallback.called).to.equal(true);
|
||||||
expect(qrCallback.called).to.equal(false);
|
expect(qrCallback.called).to.equal(false);
|
||||||
|
|
||||||
await client.destroy();
|
await client.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('LegacySessionAuth', function () {
|
|
||||||
it('should fail auth if session is invalid', async function() {
|
|
||||||
this.timeout(40000);
|
|
||||||
|
|
||||||
const authFailCallback = sinon.spy();
|
|
||||||
const qrCallback = sinon.spy();
|
|
||||||
const readyCallback = sinon.spy();
|
|
||||||
|
|
||||||
const client = helper.createClient({
|
|
||||||
options: {
|
|
||||||
authStrategy: new LegacySessionAuth({
|
|
||||||
session: {
|
|
||||||
WABrowserId: 'invalid',
|
|
||||||
WASecretBundle: 'invalid',
|
|
||||||
WAToken1: 'invalid',
|
|
||||||
WAToken2: 'invalid'
|
|
||||||
},
|
|
||||||
restartOnAuthFail: false,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
client.on('qr', qrCallback);
|
|
||||||
client.on('auth_failure', authFailCallback);
|
|
||||||
client.on('ready', readyCallback);
|
|
||||||
|
|
||||||
client.initialize();
|
|
||||||
|
|
||||||
await helper.sleep(25000);
|
|
||||||
|
|
||||||
expect(authFailCallback.called).to.equal(true);
|
|
||||||
expect(authFailCallback.args[0][0]).to.equal('Unable to log in. Are the session details valid?');
|
|
||||||
|
|
||||||
expect(readyCallback.called).to.equal(false);
|
|
||||||
expect(qrCallback.called).to.equal(false);
|
|
||||||
|
|
||||||
await client.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can restart without a session if session was invalid and restartOnAuthFail=true', async function() {
|
|
||||||
this.timeout(40000);
|
|
||||||
|
|
||||||
const authFailCallback = sinon.spy();
|
|
||||||
const qrCallback = sinon.spy();
|
|
||||||
|
|
||||||
const client = helper.createClient({
|
|
||||||
options: {
|
|
||||||
authStrategy: new LegacySessionAuth({
|
|
||||||
session: {
|
|
||||||
WABrowserId: 'invalid',
|
|
||||||
WASecretBundle: 'invalid',
|
|
||||||
WAToken1: 'invalid',
|
|
||||||
WAToken2: 'invalid'
|
|
||||||
},
|
|
||||||
restartOnAuthFail: true,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
client.on('auth_failure', authFailCallback);
|
|
||||||
client.on('qr', qrCallback);
|
|
||||||
|
|
||||||
client.initialize();
|
|
||||||
|
|
||||||
await helper.sleep(35000);
|
|
||||||
|
|
||||||
expect(authFailCallback.called).to.equal(true);
|
|
||||||
expect(qrCallback.called).to.equal(true);
|
|
||||||
expect(qrCallback.args[0][0]).to.have.length.greaterThanOrEqual(152);
|
|
||||||
|
|
||||||
await client.destroy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Non-MD only', function () {
|
|
||||||
if(!isMD) {
|
|
||||||
it('can take over if client was logged in somewhere else with takeoverOnConflict=true', async function() {
|
|
||||||
this.timeout(40000);
|
|
||||||
|
|
||||||
const readyCallback1 = sinon.spy();
|
|
||||||
const readyCallback2 = sinon.spy();
|
|
||||||
const disconnectedCallback1 = sinon.spy();
|
|
||||||
const disconnectedCallback2 = sinon.spy();
|
|
||||||
|
|
||||||
const client1 = helper.createClient({
|
|
||||||
authenticated: true,
|
|
||||||
options: { takeoverOnConflict: true, takeoverTimeoutMs: 5000 }
|
|
||||||
});
|
|
||||||
const client2 = helper.createClient({authenticated: true});
|
|
||||||
|
|
||||||
client1.on('ready', readyCallback1);
|
|
||||||
client2.on('ready', readyCallback2);
|
|
||||||
client1.on('disconnected', disconnectedCallback1);
|
|
||||||
client2.on('disconnected', disconnectedCallback2);
|
|
||||||
|
|
||||||
await client1.initialize();
|
|
||||||
expect(readyCallback1.called).to.equal(true);
|
|
||||||
expect(readyCallback2.called).to.equal(false);
|
|
||||||
expect(disconnectedCallback1.called).to.equal(false);
|
|
||||||
expect(disconnectedCallback2.called).to.equal(false);
|
|
||||||
|
|
||||||
await client2.initialize();
|
|
||||||
expect(readyCallback2.called).to.equal(true);
|
|
||||||
expect(disconnectedCallback1.called).to.equal(false);
|
|
||||||
expect(disconnectedCallback2.called).to.equal(false);
|
|
||||||
|
|
||||||
// wait for takeoverTimeoutMs to kick in
|
|
||||||
await helper.sleep(5200);
|
|
||||||
expect(disconnectedCallback1.called).to.equal(false);
|
|
||||||
expect(disconnectedCallback2.called).to.equal(true);
|
|
||||||
expect(disconnectedCallback2.calledWith(WAState.CONFLICT)).to.equal(true);
|
|
||||||
|
|
||||||
await client1.destroy();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Authenticated', function() {
|
describe('Authenticated', function() {
|
||||||
|
|
|
||||||
|
|
@ -1,51 +1,20 @@
|
||||||
const path = require('path');
|
const { Client, LocalAuth } = require('..');
|
||||||
const { Client, LegacySessionAuth, LocalAuth } = require('..');
|
|
||||||
|
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
|
|
||||||
const remoteId = process.env.WWEBJS_TEST_REMOTE_ID;
|
const remoteId = process.env.WWEBJS_TEST_REMOTE_ID;
|
||||||
if(!remoteId) throw new Error('The WWEBJS_TEST_REMOTE_ID environment variable has not been set.');
|
if(!remoteId) throw new Error('The WWEBJS_TEST_REMOTE_ID environment variable has not been set.');
|
||||||
|
|
||||||
function isUsingLegacySession() {
|
|
||||||
return Boolean(process.env.WWEBJS_TEST_SESSION || process.env.WWEBJS_TEST_SESSION_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isMD() {
|
|
||||||
return Boolean(process.env.WWEBJS_TEST_MD);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isUsingLegacySession() && isMD()) throw 'Cannot use legacy sessions with WWEBJS_TEST_MD=true';
|
|
||||||
|
|
||||||
function getSessionFromEnv() {
|
|
||||||
if (!isUsingLegacySession()) return null;
|
|
||||||
|
|
||||||
const envSession = process.env.WWEBJS_TEST_SESSION;
|
|
||||||
if(envSession) return JSON.parse(envSession);
|
|
||||||
|
|
||||||
const envSessionPath = process.env.WWEBJS_TEST_SESSION_PATH;
|
|
||||||
if(envSessionPath) {
|
|
||||||
const absPath = path.resolve(process.cwd(), envSessionPath);
|
|
||||||
return require(absPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function createClient({authenticated, options: additionalOpts}={}) {
|
function createClient({authenticated, options: additionalOpts}={}) {
|
||||||
const options = {};
|
const options = {};
|
||||||
|
|
||||||
if(authenticated) {
|
if(authenticated) {
|
||||||
const legacySession = getSessionFromEnv();
|
|
||||||
if(legacySession) {
|
|
||||||
options.authStrategy = new LegacySessionAuth({
|
|
||||||
session: legacySession
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const clientId = process.env.WWEBJS_TEST_CLIENT_ID;
|
const clientId = process.env.WWEBJS_TEST_CLIENT_ID;
|
||||||
if(!clientId) throw new Error('No session found in environment.');
|
if(!clientId) throw new Error('No session found in environment.');
|
||||||
options.authStrategy = new LocalAuth({
|
options.authStrategy = new LocalAuth({
|
||||||
clientId
|
clientId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const allOpts = {...options, ...(additionalOpts || {})};
|
const allOpts = {...options, ...(additionalOpts || {})};
|
||||||
return new Client(allOpts);
|
return new Client(allOpts);
|
||||||
|
|
@ -58,7 +27,5 @@ function sleep(ms) {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
sleep,
|
sleep,
|
||||||
createClient,
|
createClient,
|
||||||
isUsingLegacySession,
|
|
||||||
isMD,
|
|
||||||
remoteId,
|
remoteId,
|
||||||
};
|
};
|
||||||
Loading…
Reference in a new issue