UNPKG

multi-mongo

Version:

MongoDB-based auth store for Baileys with single-collection multi-session in one collection support.

149 lines (138 loc) 6.06 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.useMongoDBAuthState = useMongoDBAuthState; const { Binary } = require("mongodb"); const { proto } = require("@whiskeysockets/baileys/WAProto"); const { Curve, signedKeyPair } = require("@whiskeysockets/baileys/lib/Utils/crypto"); const { generateRegistrationId } = require("@whiskeysockets/baileys/lib/Utils/generics"); const { randomBytes } = require("crypto"); const { v4: uuidv4 } = require("uuid"); const initAuthCreds = () => { const identityKey = Curve.generateKeyPair(); return { noiseKey: Curve.generateKeyPair(), signedIdentityKey: identityKey, signedPreKey: signedKeyPair(identityKey, 1), registrationId: generateRegistrationId(), advSecretKey: randomBytes(32).toString('base64'), processedHistoryMessages: [], nextPreKeyId: 1, firstUnuploadedPreKeyId: 1, accountSyncCounter: 0, accountSettings: { unarchiveChats: false }, deviceId: randomBytes(16).toString('base64'), phoneId: uuidv4(), identityId: randomBytes(20), registered: false, backupToken: randomBytes(20), registration: {}, pairingEphemeralKeyPair: Curve.generateKeyPair(), pairingCode: undefined, lastPropHash: undefined, routingInfo: undefined, }; }; /** * Multi-device Baileys Auth State using MongoDB * @param {Collection} collection - MongoDB collection * @param {string} deviceId - Unique ID for this device/session */ function useMongoDBAuthState(collection, deviceId) { return __awaiter(this, void 0, void 0, function* () { const namespacedId = (id) => `${deviceId}-${id}`; const convertBinaryToBuffer = (obj) => { if (obj instanceof Binary) { return obj.buffer; } if (Array.isArray(obj)) { return obj.map(convertBinaryToBuffer); } if (typeof obj === 'object' && obj !== null) { const newObj = {}; for (const key in obj) { newObj[key] = convertBinaryToBuffer(obj[key]); } return newObj; } return obj; }; const writeData = (data, id) => __awaiter(this, void 0, void 0, function* () { try { yield collection.updateOne( { _id: id }, { $set: Object.assign({}, data, { deviceId }) }, { upsert: true } ); } catch (error) { console.error("Error writing data:", error); } }); const readData = (id) => __awaiter(this, void 0, void 0, function* () { try { const data = yield collection.findOne({ _id: id }); return data ? convertBinaryToBuffer(data) : null; } catch (error) { console.error("Error reading data:", error); return null; } }); const removeData = (id) => __awaiter(this, void 0, void 0, function* () { try { yield collection.deleteOne({ _id: id }); } catch (error) { console.error("Error removing data:", error); } }); // Load or initialize credentials let creds; const existingData = yield readData(namespacedId("auth_creds")); creds = existingData ? existingData.creds : initAuthCreds(); const state = { creds, keys: { get: (type, ids) => __awaiter(this, void 0, void 0, function* () { const data = {}; yield Promise.all(ids.map((id) => __awaiter(this, void 0, void 0, function* () { let value = yield readData(namespacedId(`${type}-${id}`)); if (type === "app-state-sync-key" && value) { value = proto.Message.AppStateSyncKeyData.fromObject(value); } data[id] = value; }))); return data; }), set: (data) => __awaiter(this, void 0, void 0, function* () { const tasks = []; for (const category in data) { const categoryData = data[category]; if (categoryData) { for (const id in categoryData) { const value = categoryData[id]; const key = namespacedId(`${category}-${id}`); tasks.push(value ? writeData(value, key) : removeData(key)); } } } yield Promise.all(tasks); }), }, }; return { state, saveCreds: () => __awaiter(this, void 0, void 0, function* () { yield writeData({ creds: state.creds }, namespacedId("auth_creds")); }), }; }); }