Skip to content

Commit

Permalink
fix!: Removed token store in favor of userDataDir
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Removed usage of token store to priorize userDataDir
  • Loading branch information
edgardmessias committed Mar 11, 2023
1 parent 14c2847 commit 933e5d7
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 232 deletions.
70 changes: 8 additions & 62 deletions src/api/layers/host.layer.ts
Expand Up @@ -16,40 +16,31 @@
*/

import { Page } from 'puppeteer';
import { Logger } from 'winston';
import { CreateConfig, defaultOptions } from '../../config/create-config';
import { SocketState } from '../model/enum';
import { initWhatsapp, injectApi } from '../../controllers/browser';
import { ScrapQrcode } from '../model/qrcode';
import { evaluateAndReturn, scrapeImg } from '../helpers';
import {
asciiQr,
getInterfaceStatus,
isAuthenticated,
isInsideChat,
needsToScan,
} from '../../controllers/auth';
import { sleep } from '../../utils/sleep';
import { initWhatsapp, injectApi } from '../../controllers/browser';
import { defaultLogger, LogLevel } from '../../utils/logger';
import { Logger } from 'winston';
import { sleep } from '../../utils/sleep';
import { evaluateAndReturn, scrapeImg } from '../helpers';
import {
CatchQRCallback,
HostDevice,
LoadingScreenCallback,
StatusFindCallback,
} from '../model';
import {
FileTokenStore,
isValidSessionToken,
isValidTokenStore,
MemoryTokenStore,
TokenStore,
} from '../../token-store';
import { SocketState } from '../model/enum';
import { ScrapQrcode } from '../model/qrcode';

export class HostLayer {
readonly session: string;
readonly options: CreateConfig;
readonly logger: Logger;
readonly tokenStore: TokenStore;

protected autoCloseInterval = null;
protected autoCloseCalled = false;
Expand All @@ -65,37 +56,6 @@ export class HostLayer {

this.logger = this.options.logger || defaultLogger;

if (typeof this.options.tokenStore === 'string') {
switch (this.options.tokenStore) {
case 'memory':
this.tokenStore = new MemoryTokenStore();
break;

case 'file':
default:
this.tokenStore = new FileTokenStore({
path: this.options.folderNameToken,
});
break;
}
} else {
this.tokenStore = this.options.tokenStore;
}

if (!isValidTokenStore(this.tokenStore)) {
this.log('warn', 'Invalid tokenStore, using default tokenStore', {
type: 'tokenStore',
});

if (this.options.folderNameToken) {
this.tokenStore = new FileTokenStore({
path: this.options.folderNameToken,
});
} else {
this.tokenStore = new MemoryTokenStore();
}
}

this.log('info', 'Initializing...');
this.initialize();
}
Expand All @@ -111,31 +71,17 @@ export class HostLayer {
}

protected async initialize() {
let sessionToken = this.options.sessionToken;
if (!sessionToken) {
sessionToken = await Promise.resolve(
this.tokenStore.getToken(this.session)
);
}

const isValidToken = isValidSessionToken(sessionToken);
if (isValidToken) {
this.log('verbose', 'Injecting session token', { type: 'token' });
}

const hasUserDataDir = !!this.options?.puppeteerOptions?.userDataDir;

let clear = !hasUserDataDir || (hasUserDataDir && !isValidToken);

this.page.on('close', () => {
this.cancelAutoClose();
this.log('verbose', 'Page Closed', { type: 'page' });
});

await initWhatsapp(
this.page,
sessionToken,
clear,
null,
false,
this.options.whatsappVersion,
this.log.bind(this)
);
Expand Down
60 changes: 9 additions & 51 deletions src/api/whatsapp.ts
Expand Up @@ -15,15 +15,15 @@
* along with WPPConnect. If not, see <https://www.gnu.org/licenses/>.
*/

import axios from 'axios';
import { Page } from 'puppeteer';
import { CreateConfig } from '../config/create-config';
import { useragentOverride } from '../config/WAuserAgente';
import { evaluateAndReturn } from './helpers';
import { magix, makeOptions, timeout } from './helpers/decrypt';
import { BusinessLayer } from './layers/business.layer';
import { GetMessagesParam, Message } from './model';
import { magix, timeout, makeOptions } from './helpers/decrypt';
import { useragentOverride } from '../config/WAuserAgente';
import { CreateConfig } from '../config/create-config';
import axios from 'axios';
import treekill = require('tree-kill');
import { evaluateAndReturn } from './helpers';

export class Whatsapp extends BusinessLayer {
private connected: boolean | null = null;
Expand All @@ -33,22 +33,8 @@ export class Whatsapp extends BusinessLayer {

let interval: any = null;

const removeToken = async () => {
this.log('info', 'Session Unpaired', { type: 'session' });
const removed = await Promise.resolve(
this.tokenStore.removeToken(this.session)
);

if (removed) {
this.log('verbose', 'Token removed', { type: 'token' });
}
};

if (this.page) {
this.page.on('close', async () => {
if (this.connected === false) {
await removeToken();
}
clearInterval(interval);
});
}
Expand All @@ -62,39 +48,11 @@ export class Whatsapp extends BusinessLayer {
return;
}

if (newConnected) {
this.connected = newConnected;
setTimeout(async () => {
this.log('verbose', 'Updating session token', { type: 'token' });
const tokenData = await this.getSessionTokenBrowser();
const updated = await Promise.resolve(
this.tokenStore.setToken(this.session, tokenData)
);

if (updated) {
this.log('verbose', 'Session token updated', {
type: 'token',
});
} else {
this.log('warn', 'Failed to update session token', {
type: 'token',
});
}
}, 1000);
} else {
if (!newConnected && this.connected) {
setTimeout(async () => {
await page.evaluate(() => localStorage.clear());
await page.reload();
}, 1000);
}
this.connected = newConnected;

this.connected = newConnected;
if (!newConnected) {
this.log('info', 'Session Unpaired', { type: 'session' });
setTimeout(async () => {
await removeToken();

// Fire only after a success connection and disconnection
if (newConnected && this.statusFind) {
if (this.statusFind) {
try {
this.statusFind('desconnectedMobile', session);
} catch (error) {}
Expand Down
2 changes: 2 additions & 0 deletions src/config/create-config.ts
Expand Up @@ -100,12 +100,14 @@ export interface CreateConfig {
/**
* Initial token to log in in WhatsApp.
* If not passed, the client will get it from {@link tokenStore}.
* @deprecated
*/
sessionToken?: SessionToken;

/**
* Token store used to manage token {@link tokenStore}
* @default 'file'
* @deprecated
*/
tokenStore?: TokenStore | string;

Expand Down
112 changes: 0 additions & 112 deletions src/controllers/auth.ts
Expand Up @@ -15,13 +15,8 @@
* along with WPPConnect. If not, see <https://www.gnu.org/licenses/>.
*/

import * as fs from 'fs';
import * as path from 'path';
import * as puppeteer from 'puppeteer';
import * as qrcode from 'qrcode-terminal';
import { puppeteerConfig } from '../config/puppeteer.config';
import { isValidSessionToken } from '../token-store';
import { sleep } from '../utils/sleep';

export const getInterfaceStatus = async (
waPage: puppeteer.Page
Expand Down Expand Up @@ -92,110 +87,3 @@ export async function asciiQr(code: string): Promise<string> {
});
});
}

export async function injectSessionToken(
page: puppeteer.Page,
token?: any,
clear = true
) {
if (!token || !isValidSessionToken(token)) {
token = {};
}

await page.setRequestInterception(true);

// @todo Move to another file
const reqHandler = function (req: puppeteer.PageEventObject['request']) {
if (req.url().endsWith('wppconnect-banner.jpeg')) {
req.respond({
body: fs.readFileSync(
path.resolve(__dirname + '/../../img/wppconnect-banner.jpeg')
),
contentType: 'image/jpeg',
});
return;
}

if (req.resourceType() !== 'document') {
req.continue();
return;
}

req.respond({
status: 200,
contentType: 'text/html',
body: `
<!doctype html>
<html lang=en>
<head>
<title>Initializing WhatsApp</title>
<style>
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-family: arial, sans-serif;
background-color: #e6e6e6;
}
img {
display: block;
max-width: 100%;
max-height:100%;
}
h1 {
text-align: center;
}
</style>
</head>
<body>
<div>
<img src="wppconnect-banner.jpeg" />
<h1>Initializing WhatsApp ...</h1>
</div>
</body>
</html>`,
});
};
page.on('request', reqHandler);

await page.goto(puppeteerConfig.whatsappUrl + '?_=' + Date.now());

if (clear) {
await page.evaluate(() => {
if (document.title !== 'Initializing WhatsApp') {
return;
}

localStorage.clear();

window.indexedDB
.databases()
.then((dbs) => {
dbs.forEach((db) => {
window.indexedDB.deleteDatabase(db.name);
});
})
.catch(() => null);
});

await sleep(2000);
}

if (token.WASecretBundle !== 'MultiDevice') {
await page.evaluate((session) => {
Object.keys(session).forEach((key) => {
localStorage.setItem(key, session[key]);
});
}, token as any);
}

await page.evaluate(() => {
localStorage.setItem('remember-me', 'true');
});

// Disable
page.removeAllListeners('request');

await page.setRequestInterception(false);
}
7 changes: 0 additions & 7 deletions src/controllers/browser.ts
Expand Up @@ -26,7 +26,6 @@ import puppeteer from 'puppeteer-extra';
import { CreateConfig } from '../config/create-config';
import { puppeteerConfig } from '../config/puppeteer.config';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
import { injectSessionToken } from './auth';
import { useragentOverride } from '../config/WAuserAgente';
import { WebSocketTransport } from './websocket';
import { Logger } from 'winston';
Expand Down Expand Up @@ -112,12 +111,6 @@ export async function initWhatsapp(

await unregisterServiceWorker(page);

if (clear) {
log?.('verbose', 'Cleaning localStorage');
}
// Auth with token
await injectSessionToken(page, token, clear);

if (version) {
log?.('verbose', `Setting WhatsApp WEB version to ${version}`);
await setWhatsappVersion(page, version, log);
Expand Down

0 comments on commit 933e5d7

Please sign in to comment.