A comprehensive Node.js email server that supports SMTP (sending), IMAP (retrieval), and LMTP (local transfer) protocols with modular architecture, mailbox management, and Docker deployment.
The application is organized into modular components with clear separation of concerns:
smtp-nodejs/
βββ config/ # Configuration management
β βββ config.js # Centralized configuration
β βββ database.js # Database connection management
βββ models/ # Database models
β βββ Email.js # Email schema and model (outgoing & user mailboxes)
β βββ IncomingEmail.js # Incoming email archive
β βββ SuccessfulEmail.js # Successfully sent emails
β βββ BouncedEmail.js # Bounced/failed emails
β βββ Mailbox.js # Mailbox schema and model
βββ services/ # Business logic services
β βββ MultiPortSMTPServer.js # Multi-port SMTP server
β βββ IMAPServer.js # IMAP server with modular commands
β βββ LMTPServer.js # LMTP server
β βββ EmailProcessor.js # Outgoing email processing logic
β βββ IncomingEmailProcessor.js # Incoming email delivery to mailboxes
β βββ MailSender.js # External email delivery
β βββ EmailQueue.js # Queue management
β βββ QueueAPI.js # Web dashboard and API
β βββ MailboxAPI.js # Mailbox management API
β βββ IPSelectionService.js # Dynamic IP selection
βββ services/imap/commands/ # Modular IMAP command handlers
β βββ CapabilityCommand.js
β βββ LoginCommand.js
β βββ SelectCommand.js
β βββ FetchCommand.js
β βββ SearchCommand.js
β βββ SortCommand.js
β βββ UIDCommand.js
βββ utils/ # Utility modules
β βββ logger.js # Centralized logging
βββ server.js # Main application entry point
βββ Dockerfile # Docker container definition
βββ docker-compose.yml # Multi-service deployment
βββ package.json # Dependencies and scripts
- Modular Architecture: Clean separation of concerns with dedicated modules
- Multi-Protocol Support: SMTP, IMAP, and LMTP servers
- SMTP Protocol Support: Full SMTP command handling (HELO, MAIL FROM, RCPT TO, DATA, QUIT, RSET)
- IMAP Protocol Support: Complete IMAP implementation with modular command handlers
- LMTP Protocol Support: Local mail transfer protocol implementation
- Email Processing: MIME parsing with attachment support
- Multi-Port SMTP: Support for ports 25 (forwarding), 587 (STARTTLS), and 465 (SSL)
- IMAP Server: Support for ports 143 (no SSL) and 993 (SSL) for email retrieval
- LMTP Server: Support for port 24 (no SSL) and 1024 (SSL) for local mail transfer
- Incoming Email Delivery: Automatic delivery of incoming emails from external servers to user mailboxes
- Mailbox Management: REST API for creating, deleting, and managing mailboxes
- Email Sending: DNS MX lookup and external mail server delivery
- Dynamic IP Selection: Send emails from different IP addresses based on API response
- Queue Management: Robust email queue with retry logic and failure tracking
- Separate Email Tables: Different collections for outgoing, successful, bounced, and incoming emails
- MongoDB Storage: Persistent email storage with structured schemas
- Web Dashboard: Real-time queue monitoring and management interface
- REST API: Complete API for queue management and email status
- Webhook Notifications: Success/failure notifications with detailed error information
- Configuration Management: Environment-based configuration
- Docker Support: Containerized deployment with host networking for multi-IP support
- Logging: Centralized logging with configurable levels
- Graceful Shutdown: Proper cleanup on application termination
- Error Handling: Comprehensive error handling throughout the application
-
Clone the repository
-
Install dependencies:
npm install
-
Copy the environment example and configure:
cp env.example .env
-
Update the
.env
file with your configuration
- Clone the repository
- Build and run with Docker Compose:
docker-compose up --build
Note: For multi-IP support, the Docker container uses network_mode: host
which requires Linux. For other platforms, modify docker-compose.yml
to use bridge networking.
Create a .env
file with the following options:
# Mailbox API Configuration
MAILBOX_API_PORT=8080
MAILBOX_API_KEY=changeme
# Server Configuration
SMTP_PORT=2525
SMTP_HOST=0.0.0.0
API_PORT=3000
# Multi-Port SMTP Configuration
SMTP_25_PORT=25
SMTP_465_PORT=465
SMTP_587_PORT=587
# LMTP Configuration
LMTP_24_PORT=24
LMTP_PORT=24
LMTP_SSL_PORT=1024
LMTP_SSL_ENABLED=false
LMTP_SSL_KEY=/path/to/lmtp-key.pem
LMTP_SSL_CERT=/path/to/lmtp-cert.pem
LMTP_SSL_CA=/path/to/lmtp-ca.pem
# IMAP Configuration
IMAP_143_PORT=143
IMAP_993_PORT=993
IMAP_PORT=143
IMAP_SSL_PORT=993
IMAP_SSL_ENABLED=false
IMAP_SSL_KEY=/path/to/imap-key.pem
IMAP_SSL_CERT=/path/to/imap-cert.pem
IMAP_SSL_CA=/path/to/imap-ca.pem
# Database Configuration
MONGODB_URL=mongodb://localhost:27017/smtp-server
# Email Configuration
MAX_EMAIL_SIZE=10485760
ALLOWED_DOMAINS=example.com,test.com
# Webhook Configuration
WEBHOOK_ENABLED=false
WEBHOOK_SUCCESS_URL=https://your-webhook-url.com/success
WEBHOOK_FAILURE_URL=https://your-webhook-url.com/failure
WEBHOOK_TIMEOUT=10000
WEBHOOK_RETRIES=3
# IP Selection Configuration
IP_SELECTION_ENABLED=false
IP_SELECTION_API_URL=https://your-ip-api.com/get-ip
IP_SELECTION_TIMEOUT=5000
IP_SELECTION_RETRIES=3
FALLBACK_IP=1.2.3.4
# Logging Configuration
LOG_LEVEL=info
ENABLE_CONSOLE_LOG=true
npm start
Or directly:
node server.js
docker-compose up --build
The Mailbox API runs on port 8080 by default and provides endpoints for managing email accounts:
All endpoints require the API key in the x-api-key
header or api_key
query parameter.
-
Create Mailbox
POST /api/mailboxes Content-Type: application/json x-api-key: your-api-key { "username": "[email protected]", "password": "securepassword" }
-
List Mailboxes
GET /api/mailboxes x-api-key: your-api-key
-
Delete Mailbox
DELETE /api/mailboxes/[email protected] x-api-key: your-api-key
-
Change Password
POST /api/mailboxes/[email protected]/change-password Content-Type: application/json x-api-key: your-api-key { "oldPassword": "oldpassword", "newPassword": "newpassword" }
This server supports receiving emails from external mail servers (like Gmail, Outlook, etc.) and delivering them to user mailboxes for IMAP access.
External Mail Server (Gmail)
β
Port 25 (Unauthenticated SMTP)
β
IncomingEmailProcessor
β
ββ> IncomingEmail collection (archival/logging)
ββ> Email collection (user's mailbox for IMAP)
-
Create a mailbox using the Mailbox API:
POST http://your-server:8080/api/mailboxes Content-Type: application/json x-api-key: your-api-key { "username": "test", "password": "password123" }
-
Set up MX records for your domain to point to your server's IP
-
Ensure port 25 is open for incoming connections
- Someone at
[email protected]
sends an email to[email protected]
- Gmail looks up the MX record for
example.com
β finds your server IP - Gmail connects to your port 25 (server-to-server, no authentication required)
- Your SMTP server accepts the email
- IncomingEmailProcessor processes it:
- Stores in
IncomingEmail
collection (for archival/logging) - Delivers to user's mailbox in
Email
collection withmailbox="test"
- Stores in
- User connects via IMAP (port 143 or 993) and logs in with username
test
- User sees the email in their inbox!
- β If mailbox exists: Email is delivered to the user's mailbox (visible via IMAP)
- β If mailbox doesn't exist: Email is stored in
IncomingEmail
collection only (NOT visible via IMAP) - π Logs: Check logs for
β Email delivered to mailbox
to confirm successful delivery
Run the test script to simulate an external server sending an email:
# Inside Docker container
docker exec smtp-imap-app node test-incoming-delivery.js
# Or via Vagrant
vagrant ssh -c "sudo docker exec smtp-imap-app node test-incoming-delivery.js"
This test:
- Creates a test mailbox (
testuser
) - Simulates Gmail sending an email to
[email protected]
- Verifies the email is delivered to the mailbox
- Confirms it's accessible via IMAP
HELO/EHLO
- Greeting and identificationMAIL FROM:
- Specify senderRCPT TO:
- Specify recipientsDATA
- Begin email data transmissionQUIT
- End connectionRSET
- Reset current transaction
CAPABILITY
- List server capabilitiesLOGIN
- Authenticate userSELECT
- Select mailboxLIST
- List mailboxesFETCH
- Retrieve message dataSEARCH
- Search for messagesSORT
- Sort messages by criteriaUID
- UID-based operationsNOOP
- Keep connection aliveLOGOUT
- Close connection
LHLO
- Greeting and identificationMAIL
- Specify senderRCPT
- Specify recipientsDATA
- Begin email data transmissionQUIT
- End connectionRSET
- Reset current transactionNOOP
- Keep connection alive
npm test # Test email sending
npm run test:ip # Test IP selection
npm run test:ports # Test multi-port SMTP
npm run test:lmtp # Test LMTP server
telnet localhost 2525
telnet localhost 143
telnet localhost 24
node test-separate-tables.js
Access the real-time queue dashboard at: http://localhost:3000
GET /api/queue/stats
- Get queue statisticsGET /api/emails
- List emails with paginationGET /api/emails/:id
- Get specific email detailsPOST /api/emails/:id/retry
- Retry failed emailDELETE /api/emails/:id
- Delete emailGET /api/successful-emails
- List successfully delivered emailsGET /api/successful-emails/:id
- Get specific successful email detailsGET /api/bounced-emails
- List bounced emailsGET /api/bounced-emails/:id
- Get specific bounced email detailsGET /api/incoming-emails
- List incoming emailsGET /api/incoming-emails/:id
- Get specific incoming email detailsDELETE /api/incoming-emails/:id
- Delete incoming emailGET /api/email-stats
- Get comprehensive email statisticsGET /api/ip-selection/stats
- Get IP selection cache statisticsPOST /api/ip-selection/clear-cache
- Clear IP selection cachePOST /api/ip-selection/test
- Test IP selection for specific emailGET /api/smtp/stats
- Get multi-port SMTP server statisticsGET /api/imap/stats
- Get IMAP server statisticsGET /api/lmtp/stats
- Get LMTP server statisticsGET /health
- Health check
For applications requiring multiple source IPs (e.g., email sending from different IPs), the Docker container uses network_mode: host
. This allows the container to bind to all host network interfaces and send traffic from any available source IP.
# Build and start all services
docker-compose up --build
# Run in background
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose down
Modify the docker-compose.yml
file to change default ports or use bridge networking instead of host networking.
Centralized configuration management that loads environment variables and provides defaults.
Database connection management with connection pooling and error handling.
MongoDB schema for outgoing email storage including:
- Sender and recipient information
- Subject, text, and HTML content
- Attachments with metadata
- Raw email data
- Queue management fields (status, retry count, attempts)
- References to successful and bounced email records
- Timestamps
MongoDB schema for successfully delivered emails including:
- Reference to original email
- Delivery confirmation details
- SMTP response information
- Delivery timestamp
MongoDB schema for bounced/failed emails including:
- Reference to original email
- Bounce type (hard, soft, transient, permanent)
- Bounce reason and error codes
- Bounce timestamp
MongoDB schema for incoming emails including:
- Sender and recipient information
- Source tracking (SMTP, IMAP, LMTP)
- Message headers and metadata
- Processing status
- Received timestamp
MongoDB schema for mailbox management including:
- Username and hashed password
- Creation timestamp
- Password comparison methods
Multi-port SMTP server:
- Support for ports 25, 465, and 587
- SSL/TLS support for secure connections
- Port 25 forwarding to external SMTP servers
- STARTTLS support for port 587
IMAP server for email retrieval:
- Support for ports 143 (no SSL) and 993 (SSL)
- Modular command handlers
- Database integration for email storage
- SSL/TLS support for secure connections
LMTP server for local mail transfer:
- Support for port 24 (no SSL) and 1024 (SSL)
- LMTP protocol implementation (LHLO, MAIL, RCPT, DATA, QUIT)
- Database integration for email storage
- SSL/TLS support for secure connections
Business logic for email processing:
- Email validation
- MIME parsing
- Queue management
- Error handling
Handles external email delivery:
- DNS MX record lookup
- SMTP client for external servers
- Connection management and timeout handling
- Error handling and retry logic
Queue management system:
- Email queuing and processing
- Retry logic with exponential backoff
- Failure tracking and permanent failure handling
- Queue statistics and monitoring
Web interface and API:
- REST API for queue management
- Real-time dashboard
- Email status monitoring
- Manual retry functionality
- IP selection management
Mailbox management API:
- REST API for mailbox operations
- API key authentication
- Create, delete, and manage mailboxes
- Password change functionality
Dynamic IP selection:
- API-based IP selection for email sending
- Caching mechanism for performance
- Fallback IP support
- Retry logic for API failures
Handles IMAP CAPABILITY command:
- Lists server capabilities
- Supports SORT, THREAD, and other extensions
Handles IMAP LOGIN command:
- User authentication
- State management
Handles IMAP SELECT command:
- Mailbox selection
- Status information
Handles IMAP FETCH command:
- Message data retrieval
- Multiple data item support
Handles IMAP SEARCH command:
- Message searching
- Multiple search criteria
Handles IMAP SORT command:
- Message sorting by various criteria
- Combined search and sort
Handles IMAP UID commands:
- UID-based operations
- FETCH, SEARCH, SORT, STORE
Centralized logging system with:
- Configurable log levels
- Timestamp formatting
- Console output control
- Structured logging
Emails are stored in MongoDB with the following structure:
{
sender: String,
recipients: [String],
subject: String,
text: String,
html: String,
attachments: [{
filename: String,
contentType: String,
content: Buffer
}],
raw: String,
createdAt: Date
}
The application includes comprehensive error handling:
- Database connection failures
- Email processing errors
- Protocol errors (SMTP, IMAP, LMTP)
- Graceful shutdown on system signals
- Uncaught exception handling
The server handles graceful shutdown on:
SIGTERM
(Docker/Kubernetes)SIGINT
(Ctrl+C)- Uncaught exceptions
- Unhandled promise rejections
ISC License