UNPKG

@rodrigogs/baileys-store

Version:
172 lines (171 loc) 7.62 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Keyv = exports.makeKeyvAuthState = exports.makeCacheManagerAuthState = void 0; const baileys_1 = require("baileys"); const baileys_2 = require("baileys"); const logger_1 = __importDefault(require("baileys/lib/Utils/logger")); const keyv_1 = __importDefault(require("keyv")); exports.Keyv = keyv_1.default; /** * Creates an authentication state backed by a generic key-value store (e.g. Keyv). * * @deprecated The function name is misleading as it no longer uses cache-manager. Use `makeKeyvAuthState` instead. * This function is kept as an alias for backwards compatibility. * * The returned object is compatible with Baileys' `useMultiFileAuthState` / `useSingleFileAuthState` * shape and can be passed directly to Baileys when initializing the connection. * * @param store - The storage backend used to persist credentials and keys. Can be a `Keyv` instance * or any `StorageAdapter` implementation exposing `get`, `set`, `delete`, and `clear` methods. * @param sessionKey - A unique identifier for the session. It is used as a prefix for all keys * stored in the underlying `store` so that multiple sessions can safely share the same backend. * * @returns An object containing: * - `state`: The current auth state with: * - `creds`: The loaded or newly initialized `AuthenticationCreds` instance. * - `keys`: A key store with: * - `get(type, ids)`: Asynchronously retrieves key data for the given `type` and list of `ids`, * returning an object mapping each id to its stored value (or `null` if missing). * - `set(data)`: Persists or removes key data. For each `data[category][id]`, a truthy value is * stored, and a falsy value causes the corresponding key to be deleted. * - `saveCreds()`: A function that persists the current credentials (`creds`) to the storage backend. * Call this after Baileys updates the credentials (e.g. inside the `creds.update` event handler). * - `clearState()`: A function that clears all stored data. **Important limitation**: This calls * `clear()` on the entire store, which will delete data from ALL sessions if multiple sessions * share the same store instance. This breaks session isolation. * * **Recommended solutions for session isolation (prefer option 1 for most use cases)**: * 1. Use Keyv with the `namespace` option (one namespace per session) when sharing a backend: * ```ts * const store = new Keyv({ namespace: 'session-1' }) * // clearState() will only affect this namespace while still sharing the same underlying store * ``` * This is usually more efficient than creating separate Keyv instances because it reuses the same * connection/pool while keeping per-session data isolated. * 2. Use separate store instances per session (less efficient than namespaces, but useful if your * storage backend does not support namespacing or similar isolation features). * 3. If multiple sessions share one store instance and you cannot use namespaces, avoid calling * `clearState()` and instead clear only the keys that belong to the specific session. * * @example * ```ts * import Keyv from 'keyv' * import { makeKeyvAuthState } from '@rodrigogs/baileys-store' * import makeWASocket from 'baileys' * * const store = new Keyv('sqlite://auth.db') * * async function init() { * const { state, saveCreds, clearState } = await makeKeyvAuthState(store, 'session-1') * * // Pass `state` to Baileys when creating the socket * const sock = makeWASocket({ auth: state }) * * // When credentials change, persist them * sock.ev.on('creds.update', saveCreds) * * // To fully reset this session later: * // await clearState() * } * ``` */ const makeCacheManagerAuthState = async (store, sessionKey) => { const defaultKey = (file) => `${sessionKey}:${file}`; const databaseConn = store; const writeData = async (file, data) => { let ttl = undefined; if (file === 'creds') { ttl = 63115200000; // 2 years in milliseconds } await databaseConn.set(defaultKey(file), JSON.stringify(data, baileys_2.BufferJSON.replacer), ttl); }; const readData = async (file) => { try { const data = await databaseConn.get(defaultKey(file)); if (data) { return JSON.parse(data, baileys_2.BufferJSON.reviver); } return null; } catch (error) { logger_1.default.error(error); return null; } }; const removeData = async (file) => { try { return await databaseConn.delete(defaultKey(file)); } catch (error) { logger_1.default.error(`Error removing ${file} from session ${sessionKey}:`, error); } }; const clearState = async () => { try { await databaseConn.clear(); } catch (err) { logger_1.default.error('Error clearing state:', err); } }; const creds = (await readData('creds')) || (0, baileys_2.initAuthCreds)(); return { clearState, saveCreds: () => writeData('creds', creds), state: { creds, keys: { get: async (type, ids) => { const data = {}; await Promise.all(ids.map(async (id) => { let value = await readData(`${type}-${id}`); if (type === 'app-state-sync-key' && value) { value = baileys_1.proto.Message.AppStateSyncKeyData.create(value); } data[id] = value; })); return data; }, set: async (data) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const tasks = []; for (const category in data) { for (const id in data[category]) { const value = data[category][id]; const key = `${category}-${id}`; tasks.push(value ? writeData(key, value) : removeData(key)); } } await Promise.all(tasks); }, } } }; }; exports.makeCacheManagerAuthState = makeCacheManagerAuthState; /** * Creates an authentication state backed by Keyv or any compatible storage adapter. * * This is the recommended function name that clearly indicates it works with Keyv-based storage. * Alias for `makeCacheManagerAuthState`. * * @param store - The storage backend (Keyv instance or StorageAdapter implementation) * @param sessionKey - A unique identifier for the session used as key prefix * @returns Authentication state object with state, saveCreds, and clearState * * @example * ```ts * import Keyv from 'keyv' * import { makeKeyvAuthState } from '@rodrigogs/baileys-store' * * // Recommended: Use Keyv with namespace for session isolation * const store = new Keyv({ namespace: 'session-1' }) * const { state, saveCreds } = await makeKeyvAuthState(store, 'session-1') * ``` */ const makeKeyvAuthState = makeCacheManagerAuthState; exports.makeKeyvAuthState = makeKeyvAuthState; exports.default = makeCacheManagerAuthState;