Overview
The MongoAuth class provides persistent authentication storage using MongoDB. It enables centralized session management with the benefits of document-based storage, complex querying capabilities, and robust data persistence for production-grade bot deployments.
Key Features
Document-Based Storage : Store sessions as MongoDB documents
Encrypted Storage : All session data encrypted with AES-256-GCM
Centralized Management : Single source of truth for all sessions
Query Capabilities : Leverage MongoDB’s powerful query engine
Audit Trails : Track session history and modifications
Scalability : Handle thousands of concurrent bot sessions
MongoAuth is ideal for production environments requiring centralized session management, audit capabilities, or existing MongoDB infrastructure.
Installation
MongoAuth requires the official MongoDB Node.js driver:
Constructor
new MongoAuth(uuid, collection)
Creates a new MongoAuth instance for managing bot authentication in MongoDB.
A valid UUID (v4) that uniquely identifies this bot instance. This UUID is used as the encryption key and stored with each document for session identification.
collection
Collection<IAuthState>
required
A MongoDB collection instance where authentication documents will be stored. The collection should be typed with the IAuthState interface for type safety.
Type Definition
interface IAuthState extends Document {
uuid : UUID ;
key : string ; // MD5 hash of the data key
encrypted : string ; // Base64-encoded encrypted data
}
Example
Basic Usage
With Connection String
MongoDB Atlas
With Type Safety
import { Bot , MongoAuth } from "wapi" ;
import { MongoClient } from "mongodb" ;
import { randomUUID } from "node:crypto" ;
const client = await MongoClient . connect ( "mongodb://localhost:27017" );
const db = client . db ( "wapi" );
const collection = db . collection ( "sessions" );
const uuid = randomUUID ();
const auth = new MongoAuth ( uuid , collection );
const bot = new Bot ({ auth });
Throws
Error: If the provided UUID is not a valid UUID v4 format
Properties
uuid
The UUID associated with this authentication instance. This is the same UUID provided to the constructor.
const auth = new MongoAuth ( uuid , collection );
console . log ( auth . uuid ); // "550e8400-e29b-41d4-a716-446655440000"
Methods
init()
Initializes the authentication system by loading or creating credentials and setting up the key store.
init (): Promise < IBotAuthInit >
Behavior
Credential Loading : Queries MongoDB for existing credentials using the UUID
New Session : If no credentials exist, generates new authentication credentials
Key Store Setup : Initializes the Signal protocol key store for WhatsApp encryption
Cache Population : Populates the in-memory cache with encrypted data
Returns
WhatsApp authentication credentials containing account information, encryption keys, and session state. This is managed internally by the Baileys library.
The Signal protocol key store used for end-to-end encryption. Provides get() and set() methods for managing cryptographic keys.
Example
import { MongoAuth } from "wapi" ;
import { MongoClient } from "mongodb" ;
import { randomUUID } from "node:crypto" ;
const client = await MongoClient . connect ( "mongodb://localhost:27017" );
const db = client . db ( "wapi" );
const collection = db . collection ( "sessions" );
const auth = new MongoAuth ( randomUUID (), collection );
// Initialize authentication
const { creds , keys } = await auth . init ();
console . log ( "Credentials loaded:" , !! creds );
console . log ( "Keys initialized:" , !! keys );
This method is called automatically by the Bot class during initialization. You rarely need to call it directly.
save()
Persists the current authentication credentials to MongoDB.
Behavior
Validation : Ensures credentials have been loaded via init()
Serialization : Converts credentials to JSON format
Encryption : Encrypts the data using AES-256-GCM
Upsert : Updates existing document or inserts new one
Cache Update : Updates the in-memory cache
MongoDB Operation
await collection . updateOne (
{ uuid: this . uuid , key: md5Hash },
{ $set: { encrypted: encryptedData } },
{ upsert: true }
);
Throws
Error: If credentials haven’t been initialized (“Credentials not loaded.”)
Example
import { MongoAuth } from "wapi" ;
import { MongoClient } from "mongodb" ;
import { randomUUID } from "node:crypto" ;
const client = await MongoClient . connect ( "mongodb://localhost:27017" );
const db = client . db ( "wapi" );
const collection = db . collection ( "sessions" );
const auth = new MongoAuth ( randomUUID (), collection );
// Initialize and save
await auth . init ();
await auth . save ();
console . log ( "Session saved to MongoDB" );
The Bot class automatically saves credentials when authentication state changes. Manual calls to save() are typically unnecessary.
remove()
Deletes all authentication data from MongoDB and clears the cache.
Behavior
Batch Deletion : Deletes all documents matching the bot’s UUID
Cache Clearing : Clears the in-memory cache
MongoDB Operation
await collection . deleteMany ({ uuid: this . uuid });
Example
Basic Removal
With Bot Instance
import { MongoAuth } from "wapi" ;
import { MongoClient } from "mongodb" ;
import { randomUUID } from "node:crypto" ;
const client = await MongoClient . connect ( "mongodb://localhost:27017" );
const db = client . db ( "wapi" );
const collection = db . collection ( "sessions" );
const uuid = randomUUID ();
const auth = new MongoAuth ( uuid , collection );
// Remove session data
await auth . remove ();
console . log ( "Session removed from MongoDB" );
This operation is irreversible. After calling remove(), the bot will need to re-authenticate (scan QR code or enter OTP) on next startup.
Storage Details
Document Structure
Each session data point is stored as a separate document:
{
_id : ObjectId ( "..." ),
uuid : "550e8400-e29b-41d4-a716-446655440000" ,
key : "5f4dcc3b5aa765d61d8327deb882cf99" ,
encrypted : "AES-encrypted-base64-string..."
}
Field Descriptions
MongoDB’s unique document identifier, automatically generated.
The bot’s unique identifier. Used to query all documents belonging to a specific bot session.
MD5 hash of the original key name (e.g., “creds”, “pre-key-1”). Ensures consistent document identification.
Base64-encoded AES-256-GCM encrypted data. Contains the actual session information.
Indexes
Create these indexes for optimal performance:
// Compound index for fast lookups
await collection . createIndex ({ uuid: 1 , key: 1 }, { unique: true });
// Index for bulk operations
await collection . createIndex ({ uuid: 1 });
Encryption
Algorithm
Process
Decryption
Cipher : AES-256-GCM (Galois/Counter Mode)
Key : Derived from the bot’s UUID
Security : Authenticated encryption with associated data (AEAD)
Format : Encrypted data stored as base64 strings
Original data is JSON-stringified
Buffers are converted to base64 strings
Result is encrypted with AES-256-GCM
Encrypted bytes are base64-encoded
Base64 string is stored in MongoDB
Fetch document from MongoDB
Base64-decode the encrypted field
Decrypt using AES-256-GCM with UUID key
Parse JSON and restore Buffer objects
Return deserialized data
Complete Examples
Basic Bot
Multi-Bot Setup
Session Management Dashboard
With Connection Pooling
Graceful Shutdown
import { Bot , MongoAuth } from "wapi" ;
import { MongoClient } from "mongodb" ;
import { randomUUID } from "node:crypto" ;
const client = await MongoClient . connect (
process . env . MONGODB_URI || "mongodb://localhost:27017"
);
const db = client . db ( "wapi" );
const collection = db . collection ( "sessions" );
const uuid = randomUUID ();
const auth = new MongoAuth ( uuid , collection );
const bot = new Bot ({ auth });
bot . on ( "qr" , ( qr ) => {
console . log ( "Scan this QR code:" , qr );
});
bot . on ( "open" , ( account ) => {
console . log ( "Connected as:" , account . name );
});
bot . command ( "hello" , ( ctx ) => {
ctx . reply ( "Hello from MongoAuth!" );
});
await bot . launch ();
Advanced Configuration
MongoDB Atlas
Connect to MongoDB Atlas for cloud-hosted storage:
import { Bot , MongoAuth } from "wapi" ;
import { MongoClient , ServerApiVersion } from "mongodb" ;
import { randomUUID } from "node:crypto" ;
const uri = `mongodb+srv:// ${ process . env . MONGO_USER } : ${ process . env . MONGO_PASS } @cluster.mongodb.net/?retryWrites=true&w=majority` ;
const client = new MongoClient ( uri , {
serverApi: {
version: ServerApiVersion . v1 ,
strict: true ,
deprecationErrors: true ,
},
});
await client . connect ();
const db = client . db ( "production" );
const collection = db . collection ( "wapi_sessions" );
const auth = new MongoAuth ( randomUUID (), collection );
const bot = new Bot ({ auth });
await bot . launch ();
Replica Sets
Connect to MongoDB replica set for high availability:
import { Bot , MongoAuth } from "wapi" ;
import { MongoClient } from "mongodb" ;
import { randomUUID } from "node:crypto" ;
const uri = "mongodb://host1:27017,host2:27017,host3:27017/?replicaSet=myReplicaSet" ;
const client = new MongoClient ( uri , {
readPreference: "primaryPreferred" ,
w: "majority" ,
retryWrites: true ,
});
await client . connect ();
const db = client . db ( "wapi" );
const collection = db . collection ( "sessions" );
const auth = new MongoAuth ( randomUUID (), collection );
const bot = new Bot ({ auth });
await bot . launch ();
Session Analytics
Implement analytics using MongoDB aggregation:
// Count sessions by creation date
const sessionsByDate = await collection . aggregate ([
{
$group: {
_id: { $dateToString: { format: "%Y-%m-%d" , date: "$_id" } },
count: { $sum: 1 },
},
},
{ $sort: { _id: - 1 } },
]). toArray ();
// Find largest sessions
const largestSessions = await collection . aggregate ([
{
$group: {
_id: "$uuid" ,
documentCount: { $sum: 1 },
totalSize: { $sum: { $bsonSize: "$$ROOT" } },
},
},
{ $sort: { totalSize: - 1 } },
{ $limit: 10 },
]). toArray ();
console . log ( "Largest sessions:" , largestSessions );
Advantages
Persistence
Scalability
Query Power
Management
✅ Durable storage
✅ Backup & restore
✅ Point-in-time recovery
✅ Data retention policies
✅ Archive capabilities
📈 Horizontal scaling
📈 Sharding support
📈 Replica sets
📈 Load distribution
📈 Handle millions of sessions
🔍 Complex queries
🔍 Aggregation pipelines
🔍 Full-text search
🔍 Geospatial queries
🔍 Analytics capabilities
🛠️ Centralized control
🛠️ Audit trails
🛠️ Session monitoring
🛠️ User management
🛠️ Admin dashboards
Best Practices
Follow these recommendations for optimal performance and reliability:
1. Indexing Strategy
// Create compound index for lookups
await collection . createIndex (
{ uuid: 1 , key: 1 },
{ unique: true , background: true }
);
// Create index for bulk operations
await collection . createIndex (
{ uuid: 1 },
{ background: true }
);
2. Connection Reuse
// ✅ Good: Reuse MongoDB client
const client = await MongoClient . connect ( uri );
const collection = client . db ( "wapi" ). collection ( "sessions" );
const auth1 = new MongoAuth ( uuid1 , collection );
const auth2 = new MongoAuth ( uuid2 , collection );
// ❌ Bad: Create new connection per bot
const auth1 = new MongoAuth (
uuid1 ,
( await MongoClient . connect ( uri )). db ( "wapi" ). collection ( "sessions" )
);
3. Error Handling
try {
await client . connect ();
await client . db ( "admin" ). command ({ ping: 1 });
console . log ( "MongoDB connected successfully" );
} catch ( error ) {
console . error ( "MongoDB connection failed:" , error );
process . exit ( 1 );
}
4. Data Cleanup
// Remove stale sessions periodically
setInterval ( async () => {
const cutoffDate = new Date ( Date . now () - 30 * 24 * 60 * 60 * 1000 ); // 30 days
const result = await collection . deleteMany ({
_id: { $lt: cutoffDate },
});
console . log ( `Cleaned up ${ result . deletedCount } stale documents` );
}, 24 * 60 * 60 * 1000 ); // Daily
Troubleshooting
Connection Issues
Show Cannot connect to MongoDB
// Test connection
try {
await client . connect ();
await client . db ( "admin" ). command ({ ping: 1 });
console . log ( "Successfully connected to MongoDB" );
} catch ( error ) {
console . error ( "Connection failed:" , error );
}
Show Authentication errors
const client = new MongoClient ( uri , {
auth: {
username: process . env . MONGO_USER ,
password: process . env . MONGO_PASS ,
},
authSource: "admin" ,
});
Create appropriate indexes
Use explain() to analyze queries
Enable profiling: db.setProfilingLevel(1, { slowms: 100 })
Monitor with MongoDB Atlas Performance Advisor
Implement document size limits
Use projections to fetch only needed fields
Enable compression: compressors: ["snappy", "zlib"]
Monitor collection stats: db.collection.stats()
When to Use
Use MongoAuth
Use RedisAuth
Use LocalAuth
✅ Long-term persistence
✅ Audit trail requirements
✅ Complex querying needs
✅ Centralized management
✅ Existing MongoDB infrastructure
✅ Session analytics
✅ Multi-tenant applications
⚡ Speed priority
⚡ Session migration
⚡ High-availability
⚡ Temporary sessions
📁 Single-server deployments
📁 Development/testing
📁 Minimal dependencies
See Also