9.6 KiB
Prosody Node.js
A full-featured XMPP (Jabber) server implementation in Node.js, inspired by the Prosody XMPP server.
Features
-
Full XMPP Protocol Support
- Client-to-Server (C2S) connections over TCP/TLS
- Server-to-Server (S2S) federation (in progress)
- BOSH (HTTP binding) support
- WebSocket support
- Component protocol (XEP-0114)
-
Core XMPP Features
- User authentication (PLAIN, SCRAM-SHA-1)
- Roster management
- Presence handling
- Message routing and delivery
- IQ request/response handling
- Service discovery (disco)
-
Advanced Features
- Multi-user chat (MUC) support
- Message Archive Management (MAM)
- Message Carbons
- Client State Indication (CSI)
- Publish-Subscribe (PubSub)
- Personal Eventing Protocol (PEP)
- File sharing
- vCard support
- Blocklist management
- Bookmarks
-
Server Architecture
- Modular plugin system
- Virtual host support
- Flexible configuration
- Multiple storage backends
- Comprehensive logging
- Rate limiting
- Connection limits
Requirements
- Node.js >= 18.0.0
- npm or yarn
Installation
# Clone the repository
git clone https://github.com/yourusername/prosody-nodejs.git
cd prosody-nodejs
# Install dependencies
npm install
# Copy example environment file
cp .env.example .env
# Edit configuration
nano config/default.yaml
Configuration
The server can be configured through:
- YAML Configuration File (
config/default.yaml) - Environment Variables (
.env) - Custom Configuration File (passed to server)
Basic Configuration
# config/default.yaml
server:
domain: localhost
version: "1.0.0"
network:
c2s:
enabled: true
port: 5222
tls:
enabled: true
virtualHosts:
- domain: localhost
enabled: true
modules:
- roster
- saslauth
- tls
- disco
Environment Variables
# .env
SERVER_PORT=5222
SERVER_HOST=localhost
TLS_ENABLED=true
STORAGE_TYPE=memory
LOG_LEVEL=info
Usage
Starting the Server
# Development mode (with auto-reload)
npm run dev
# Production mode
npm start
Running Tests
npm test
Linting
npm run lint
Architecture
Core Components
Server
The main server class that orchestrates all components:
- Initializes core managers
- Starts network listeners
- Manages server lifecycle
Config Manager
Handles configuration loading and management:
- YAML file parsing
- Environment variable override
- Configuration merging
Session Manager
Manages all active client sessions:
- Session creation and authentication
- JID mapping
- Session lifecycle management
Host Manager
Manages virtual hosts:
- Multi-domain support
- Per-host configuration
- Host-specific module loading
Module Manager
Plugin system for extending functionality:
- Module loading/unloading
- Module lifecycle hooks
- Dependency management
Stanza Router
Routes XMPP stanzas to their destinations:
- Message routing
- Presence broadcasting
- IQ handling
- Filtering and hooks
Storage Manager
Abstracts data persistence:
- Multiple backend support (memory, file, database)
- Per-host storage isolation
- Key-value and document storage
Network Servers
C2S Server (Client-to-Server)
Handles direct client connections:
- TCP and TLS support
- XMPP stream negotiation
- SASL authentication
- Resource binding
S2S Server (Server-to-Server)
Federation with other XMPP servers:
- Dialback authentication
- Certificate validation
- Connection pooling
BOSH Server
HTTP binding for web clients:
- Long-polling support
- Session management
- Cross-origin support
WebSocket Server
Modern WebSocket-based XMPP:
- Binary and text frames
- XMPP framing protocol
- Sub-protocol negotiation
Component Server
External component connections:
- Component authentication
- Stanza routing
- Component management
Module Development
Create custom modules to extend server functionality:
// modules/mod_example.js
module.exports = {
name: 'example',
version: '1.0.0',
load(module) {
const { logger, config, stanzaRouter } = module.api;
logger.info('Example module loaded');
// Hook into events
stanzaRouter.on('message', (stanza, session) => {
logger.debug('Message received:', stanza.toString());
});
},
unload(module) {
module.api.logger.info('Example module unloaded');
}
};
API Reference
Session API
// Create a session
const session = sessionManager.createSession({
id: 'session-id',
jid: 'user@domain/resource',
type: 'c2s'
});
// Get session by JID
const session = sessionManager.getSessionByJid('user@domain/resource');
// Close session
sessionManager.closeSession(sessionId);
Storage API
// Get a store
const store = storageManager.getStore('domain', 'storeName');
// Store data
await store.set('key', { data: 'value' });
// Retrieve data
const data = await store.get('key');
// Find data
const results = await store.find(item => item.data === 'value');
Stanza Routing
// Route a stanza
stanzaRouter.route(stanza, session);
// Add a filter
stanzaRouter.addFilter((stanza, session) => {
// Return false to block stanza
return true;
});
// Listen for events
stanzaRouter.on('message', (stanza, session) => {
// Handle message
});
Security
Best Practices
- TLS/SSL: Always enable TLS for production
- Authentication: Use strong authentication mechanisms
- Rate Limiting: Configure rate limits to prevent abuse
- Connection Limits: Set per-IP connection limits
- Input Validation: Validate all stanza content
- Logging: Monitor logs for suspicious activity
Configuration
security:
maxStanzaSize: 262144
connectionTimeout: 60000
maxConnectionsPerIP: 5
tlsCiphers: "HIGH:!aNULL:!MD5"
rateLimit:
enabled: true
maxPointsPerSecond: 10
blockDuration: 60
Performance
Optimization Tips
- Clustering: Run multiple instances behind a load balancer
- Storage: Use proper database for production (not memory)
- Caching: Enable caching for frequently accessed data
- Compression: Enable stream compression
- Monitoring: Use monitoring tools to track performance
Metrics
The server exposes metrics for monitoring:
- Active sessions
- Message throughput
- CPU and memory usage
- Storage operations
- Error rates
Troubleshooting
Common Issues
Connection Refused
- Check if the server is running
- Verify port configuration
- Check firewall settings
Authentication Failed
- Verify credentials
- Check authentication backend
- Review logs for errors
TLS Errors
- Verify certificate paths
- Check certificate validity
- Ensure proper permissions
Debug Mode
Enable debug logging:
LOG_LEVEL=debug npm start
Contributing
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch
- Write tests for new features
- Ensure all tests pass
- Submit a pull request
License
MIT License - see LICENSE file for details
Credits
Inspired by Prosody XMPP Server written in Lua.
Support
- Documentation: docs/
- Issues: GitHub Issues
- Community: XMPP MUC at prosody-nodejs@conference.example.com
Roadmap
Version 1.0
- Core XMPP protocol
- C2S connections
- Basic authentication
- Message routing
- Full S2S federation
- Complete BOSH implementation
- Complete WebSocket implementation
Version 1.1
- Advanced authentication (SCRAM, EXTERNAL)
- Stream Management (XEP-0198)
- Message Archive Management
- Multi-user chat
- HTTP file upload
Version 2.0
- Clustering support
- Database storage backends
- Admin interface
- Metrics and monitoring
- Push notifications
- Advanced security features
Examples
Basic Client Connection
// Using node-xmpp-client
const xmpp = require('node-xmpp-client');
const client = new xmpp.Client({
jid: 'user@localhost',
password: 'password',
host: 'localhost',
port: 5222
});
client.on('online', () => {
console.log('Connected!');
// Send presence
client.send(new xmpp.Element('presence'));
// Send message
const message = new xmpp.Element('message', {
to: 'friend@localhost',
type: 'chat'
}).c('body').t('Hello!');
client.send(message);
});
Custom Module Example
See docs/MODULE_DEVELOPMENT.md for detailed guide.
Comparison with Prosody
| Feature | Prosody (Lua) | Prosody Node.js |
|---|---|---|
| Language | Lua | JavaScript/Node.js |
| Protocol Support | Full XMPP | Core XMPP (expanding) |
| Module System | Yes | Yes |
| Performance | Excellent | Good (improving) |
| Memory Usage | Low | Moderate |
| Ease of Use | Easy | Easy |
| Community | Large | Growing |
FAQ
Q: Why Node.js instead of Lua? A: Node.js offers a larger ecosystem, easier deployment, and familiarity for web developers.
Q: Is it production-ready? A: Core features are stable. S2S federation and some advanced features are still in development.
Q: Can it replace Prosody? A: For basic XMPP needs, yes. For advanced deployments, Prosody is still recommended.
Q: What about performance? A: Node.js provides good performance for most use cases. Benchmarks show comparable throughput.