@rodrigogs/baileys-store
Version:
Baileys Store
172 lines (171 loc) • 7.62 kB
JavaScript
;
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;