mirror of
https://github.com/cheveguerra/whatsapp-web.js.git
synced 2026-04-17 19:26:20 +00:00
258 lines
10 KiB
HTML
258 lines
10 KiB
HTML
<!doctype html>
|
|
<html>
|
|
|
|
<head>
|
|
<meta name="generator" content="JSDoc 3.6.7">
|
|
<meta charset="utf-8">
|
|
<title>whatsapp-web.js 1.18.4 » Source: authStrategies/RemoteAuth.js</title>
|
|
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
|
|
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
|
|
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
|
|
<link href="css/baseline.css" rel="stylesheet">
|
|
</head>
|
|
|
|
<body onload="prettyPrint()">
|
|
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
|
|
<div id="jsdoc-navbar-container">
|
|
<div id="jsdoc-navbar-content">
|
|
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>18.<wbr>4</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
<div id="jsdoc-body-container">
|
|
<div id="jsdoc-content">
|
|
<div id="jsdoc-content-container">
|
|
<div id="jsdoc-banner" role="banner">
|
|
</div>
|
|
<div id="jsdoc-main" role="main">
|
|
<header class="page-header">
|
|
<h1>Source: authStrategies/RemoteAuth.js</h1>
|
|
</header>
|
|
<article>
|
|
<pre class="prettyprint linenums"><code>'use strict';
|
|
|
|
/* Require Optional Dependencies */
|
|
try {
|
|
var fs = require('fs-extra');
|
|
var unzipper = require('unzipper');
|
|
var archiver = require('archiver');
|
|
} catch {
|
|
fs = undefined;
|
|
unzipper = undefined;
|
|
archiver = undefined;
|
|
}
|
|
|
|
const path = require('path');
|
|
const { Events } = require('./../util/Constants');
|
|
const BaseAuthStrategy = require('./BaseAuthStrategy');
|
|
|
|
/**
|
|
* Remote-based authentication
|
|
* @param {object} options - options
|
|
* @param {object} options.store - Remote database store instance
|
|
* @param {string} options.clientId - Client id to distinguish instances if you are using multiple, otherwise keep null if you are using only one instance
|
|
* @param {string} options.dataPath - Change the default path for saving session files, default is: "./.wwebjs_auth/"
|
|
* @param {number} options.backupSyncIntervalMs - Sets the time interval for periodic session backups. Accepts values starting from 60000ms {1 minute}
|
|
*/
|
|
class RemoteAuth extends BaseAuthStrategy {
|
|
constructor({ clientId, dataPath, store, backupSyncIntervalMs } = {}) {
|
|
if (!fs &amp;&amp; !unzipper &amp;&amp; !archiver) throw new Error('Optional Dependencies [fs-extra, unzipper, archiver] are required to use RemoteAuth. Make sure to run npm install correctly and remove the --no-optional flag');
|
|
super();
|
|
|
|
const idRegex = /^[-_\w]+$/i;
|
|
if (clientId &amp;&amp; !idRegex.test(clientId)) {
|
|
throw new Error('Invalid clientId. Only alphanumeric characters, underscores and hyphens are allowed.');
|
|
}
|
|
if (!backupSyncIntervalMs || backupSyncIntervalMs &lt; 60000) {
|
|
throw new Error('Invalid backupSyncIntervalMs. Accepts values starting from 60000ms {1 minute}.');
|
|
}
|
|
if(!store) throw new Error('Remote database store is required.');
|
|
|
|
this.store = store;
|
|
this.clientId = clientId;
|
|
this.backupSyncIntervalMs = backupSyncIntervalMs;
|
|
this.dataPath = path.resolve(dataPath || './.wwebjs_auth/');
|
|
this.tempDir = `${this.dataPath}/wwebjs_temp_session`;
|
|
this.requiredDirs = ['Default', 'IndexedDB', 'Local Storage']; /* => Required Files &amp; Dirs in WWebJS to restore session */
|
|
}
|
|
|
|
async beforeBrowserInitialized() {
|
|
const puppeteerOpts = this.client.options.puppeteer;
|
|
const sessionDirName = this.clientId ? `RemoteAuth-${this.clientId}` : 'RemoteAuth';
|
|
const dirPath = path.join(this.dataPath, sessionDirName);
|
|
|
|
if (puppeteerOpts.userDataDir &amp;&amp; puppeteerOpts.userDataDir !== dirPath) {
|
|
throw new Error('RemoteAuth is not compatible with a user-supplied userDataDir.');
|
|
}
|
|
|
|
this.userDataDir = dirPath;
|
|
this.sessionName = sessionDirName;
|
|
|
|
await this.extractRemoteSession();
|
|
|
|
this.client.options.puppeteer = {
|
|
...puppeteerOpts,
|
|
userDataDir: dirPath
|
|
};
|
|
}
|
|
|
|
async logout() {
|
|
await this.disconnect();
|
|
}
|
|
|
|
async destroy() {
|
|
clearInterval(this.backupSync);
|
|
}
|
|
|
|
async disconnect() {
|
|
await this.deleteRemoteSession();
|
|
|
|
let pathExists = await this.isValidPath(this.userDataDir);
|
|
if (pathExists) {
|
|
await fs.promises.rm(this.userDataDir, {
|
|
recursive: true,
|
|
force: true
|
|
}).catch(() => {});
|
|
}
|
|
clearInterval(this.backupSync);
|
|
}
|
|
|
|
async afterAuthReady() {
|
|
const sessionExists = await this.store.sessionExists({session: this.sessionName});
|
|
if(!sessionExists) {
|
|
await this.delay(60000); /* Initial delay sync required for session to be stable enough to recover */
|
|
await this.storeRemoteSession({emit: true});
|
|
}
|
|
var self = this;
|
|
this.backupSync = setInterval(async function () {
|
|
await self.storeRemoteSession();
|
|
}, this.backupSyncIntervalMs);
|
|
}
|
|
|
|
async storeRemoteSession(options) {
|
|
/* Compress &amp; Store Session */
|
|
const pathExists = await this.isValidPath(this.userDataDir);
|
|
if (pathExists) {
|
|
await this.compressSession();
|
|
await this.store.save({session: this.sessionName});
|
|
await fs.promises.unlink(`${this.sessionName}.zip`);
|
|
await fs.promises.rm(`${this.tempDir}`, {
|
|
recursive: true,
|
|
force: true
|
|
}).catch(() => {});
|
|
if(options &amp;&amp; options.emit) this.client.emit(Events.REMOTE_SESSION_SAVED);
|
|
}
|
|
}
|
|
|
|
async extractRemoteSession() {
|
|
const pathExists = await this.isValidPath(this.userDataDir);
|
|
const compressedSessionPath = `${this.sessionName}.zip`;
|
|
const sessionExists = await this.store.sessionExists({session: this.sessionName});
|
|
if (pathExists) {
|
|
await fs.promises.rm(this.userDataDir, {
|
|
recursive: true,
|
|
force: true
|
|
}).catch(() => {});
|
|
}
|
|
if (sessionExists) {
|
|
await this.store.extract({session: this.sessionName, path: compressedSessionPath});
|
|
await this.unCompressSession(compressedSessionPath);
|
|
} else {
|
|
fs.mkdirSync(this.userDataDir, { recursive: true });
|
|
}
|
|
}
|
|
|
|
async deleteRemoteSession() {
|
|
const sessionExists = await this.store.sessionExists({session: this.sessionName});
|
|
if (sessionExists) await this.store.delete({session: this.sessionName});
|
|
}
|
|
|
|
async compressSession() {
|
|
const archive = archiver('zip');
|
|
const stream = fs.createWriteStream(`${this.sessionName}.zip`);
|
|
|
|
await fs.copy(this.userDataDir, this.tempDir).catch(() => {});
|
|
await this.deleteMetadata();
|
|
return new Promise((resolve, reject) => {
|
|
archive
|
|
.directory(this.tempDir, false)
|
|
.on('error', err => reject(err))
|
|
.pipe(stream);
|
|
|
|
stream.on('close', () => resolve());
|
|
archive.finalize();
|
|
});
|
|
}
|
|
|
|
async unCompressSession(compressedSessionPath) {
|
|
var stream = fs.createReadStream(compressedSessionPath);
|
|
await new Promise((resolve, reject) => {
|
|
stream.pipe(unzipper.Extract({
|
|
path: this.userDataDir
|
|
}))
|
|
.on('error', err => reject(err))
|
|
.on('finish', () => resolve());
|
|
});
|
|
await fs.promises.unlink(compressedSessionPath);
|
|
}
|
|
|
|
async deleteMetadata() {
|
|
const sessionDirs = [this.tempDir, path.join(this.tempDir, 'Default')];
|
|
for (const dir of sessionDirs) {
|
|
const sessionFiles = await fs.promises.readdir(dir);
|
|
for (const element of sessionFiles) {
|
|
if (!this.requiredDirs.includes(element)) {
|
|
const dirElement = path.join(dir, element);
|
|
const stats = await fs.promises.lstat(dirElement);
|
|
|
|
if (stats.isDirectory()) {
|
|
await fs.promises.rm(dirElement, {
|
|
recursive: true,
|
|
force: true
|
|
}).catch(() => {});
|
|
} else {
|
|
await fs.promises.unlink(dirElement).catch(() => {});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async isValidPath(path) {
|
|
try {
|
|
await fs.promises.access(path);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async delay(ms) {
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
}
|
|
}
|
|
|
|
module.exports = RemoteAuth;
|
|
</code></pre>
|
|
</article>
|
|
</div>
|
|
</div>
|
|
<nav id="jsdoc-toc-nav" role="navigation"></nav>
|
|
</div>
|
|
</div>
|
|
<footer id="jsdoc-footer" class="jsdoc-footer">
|
|
<div id="jsdoc-footer-container">
|
|
<p>
|
|
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on November 26, 2022.
|
|
</p>
|
|
</div>
|
|
</footer>
|
|
<script src="scripts/jquery.min.js"></script>
|
|
<script src="scripts/tree.jquery.js"></script>
|
|
<script src="scripts/prettify.js"></script>
|
|
<script src="scripts/jsdoc-toc.js"></script>
|
|
<script src="scripts/linenumber.js"></script>
|
|
<script src="scripts/scrollanchor.js"></script>
|
|
</body>
|
|
|
|
</html> |