Spaces:
Runtime error
Runtime error
| import * as fs from 'fs'; | |
| import * as path from 'path'; | |
| import pino, { Logger } from 'pino'; | |
| import { AuthStrategy, Client } from 'whatsapp-web.js'; | |
| async function isValidPath(path: string) { | |
| try { | |
| await fs.promises.access(path); | |
| return true; | |
| } catch { | |
| return false; | |
| } | |
| } | |
| export class LocalAuth implements AuthStrategy { | |
| private readonly logger: Logger; | |
| private client: Client; | |
| private readonly clientId: string; | |
| private readonly dataPath: string; | |
| private readonly rmMaxRetries: number; | |
| private userDataDir: string; | |
| setup(client: Client) { | |
| this.client = client; | |
| } | |
| constructor({ clientId, dataPath, rmMaxRetries, logger }) { | |
| const idRegex = /^[-_\w]+$/i; | |
| if (clientId && !idRegex.test(clientId)) { | |
| throw new Error( | |
| 'Invalid clientId. Only alphanumeric characters, underscores and hyphens are allowed.', | |
| ); | |
| } | |
| this.dataPath = path.resolve(dataPath || './.wwebjs_auth/'); | |
| this.clientId = clientId; | |
| this.rmMaxRetries = rmMaxRetries ?? 4; | |
| this.logger = logger || pino({ name: LocalAuth.name }); | |
| } | |
| async beforeBrowserInitialized() { | |
| // @ts-ignore | |
| const puppeteerOpts = this.client.options.puppeteer; | |
| const sessionDirName = this.clientId | |
| ? `session-${this.clientId}` | |
| : 'session'; | |
| const dirPath = path.join(this.dataPath, sessionDirName); | |
| if (puppeteerOpts.userDataDir && puppeteerOpts.userDataDir !== dirPath) { | |
| throw new Error( | |
| 'LocalAuth is not compatible with a user-supplied userDataDir.', | |
| ); | |
| } | |
| fs.mkdirSync(dirPath, { recursive: true }); | |
| // @ts-ignore | |
| this.client.options.puppeteer = { | |
| ...puppeteerOpts, | |
| userDataDir: dirPath, | |
| }; | |
| this.userDataDir = dirPath; | |
| await this.removeSingletonFiles(dirPath); | |
| } | |
| /** | |
| * Find in direction Singleton* files and try to remove it | |
| * Fix for SingletonLock and other files | |
| */ | |
| private async removeSingletonFiles(dir: string) { | |
| const files = await fs.promises.readdir(dir); | |
| for (const file of files) { | |
| if (file.startsWith('Singleton')) { | |
| const filePath = path.join(dir, file); | |
| try { | |
| await fs.promises.rm(filePath, { | |
| maxRetries: this.rmMaxRetries, | |
| recursive: true, | |
| force: true, | |
| }); | |
| } catch (err) { | |
| this.logger.error(err, `Error deleting: ${filePath}`); | |
| } | |
| } | |
| } | |
| } | |
| async logout() { | |
| if (this.userDataDir) { | |
| await this.removePathSilently(this.userDataDir); | |
| } | |
| } | |
| private async removePathSilently(path: string) { | |
| const exists = await isValidPath(path); | |
| if (!exists) { | |
| return; | |
| } | |
| try { | |
| await fs.promises.rm(path, { | |
| maxRetries: this.rmMaxRetries, | |
| recursive: true, | |
| force: true, | |
| }); | |
| } catch (err) { | |
| this.logger.error(err, `Error deleting: ${path}`); | |
| } | |
| } | |
| async afterBrowserInitialized() { | |
| return; | |
| } | |
| async onAuthenticationNeeded() { | |
| return { | |
| failed: false, | |
| restart: false, | |
| failureEventPayload: undefined, | |
| }; | |
| } | |
| async getAuthEventPayload() { | |
| return; | |
| } | |
| async afterAuthReady() { | |
| return; | |
| } | |
| async disconnect() { | |
| return; | |
| } | |
| async destroy() { | |
| return; | |
| } | |
| } | |