482 líneas
9.6 KiB
Markdown
482 líneas
9.6 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
1. **YAML Configuration File** (`config/default.yaml`)
|
|
2. **Environment Variables** (`.env`)
|
|
3. **Custom Configuration File** (passed to server)
|
|
|
|
### Basic Configuration
|
|
|
|
```yaml
|
|
# 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
|
|
|
|
```bash
|
|
# .env
|
|
SERVER_PORT=5222
|
|
SERVER_HOST=localhost
|
|
TLS_ENABLED=true
|
|
STORAGE_TYPE=memory
|
|
LOG_LEVEL=info
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Starting the Server
|
|
|
|
```bash
|
|
# Development mode (with auto-reload)
|
|
npm run dev
|
|
|
|
# Production mode
|
|
npm start
|
|
```
|
|
|
|
### Running Tests
|
|
|
|
```bash
|
|
npm test
|
|
```
|
|
|
|
### Linting
|
|
|
|
```bash
|
|
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:
|
|
|
|
```javascript
|
|
// 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
|
|
|
|
```javascript
|
|
// 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
|
|
|
|
```javascript
|
|
// 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
|
|
|
|
```javascript
|
|
// 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
|
|
|
|
1. **TLS/SSL**: Always enable TLS for production
|
|
2. **Authentication**: Use strong authentication mechanisms
|
|
3. **Rate Limiting**: Configure rate limits to prevent abuse
|
|
4. **Connection Limits**: Set per-IP connection limits
|
|
5. **Input Validation**: Validate all stanza content
|
|
6. **Logging**: Monitor logs for suspicious activity
|
|
|
|
### Configuration
|
|
|
|
```yaml
|
|
security:
|
|
maxStanzaSize: 262144
|
|
connectionTimeout: 60000
|
|
maxConnectionsPerIP: 5
|
|
tlsCiphers: "HIGH:!aNULL:!MD5"
|
|
|
|
rateLimit:
|
|
enabled: true
|
|
maxPointsPerSecond: 10
|
|
blockDuration: 60
|
|
```
|
|
|
|
## Performance
|
|
|
|
### Optimization Tips
|
|
|
|
1. **Clustering**: Run multiple instances behind a load balancer
|
|
2. **Storage**: Use proper database for production (not memory)
|
|
3. **Caching**: Enable caching for frequently accessed data
|
|
4. **Compression**: Enable stream compression
|
|
5. **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:
|
|
|
|
```bash
|
|
LOG_LEVEL=debug npm start
|
|
```
|
|
|
|
## Contributing
|
|
|
|
Contributions are welcome! Please follow these guidelines:
|
|
|
|
1. Fork the repository
|
|
2. Create a feature branch
|
|
3. Write tests for new features
|
|
4. Ensure all tests pass
|
|
5. Submit a pull request
|
|
|
|
## License
|
|
|
|
MIT License - see LICENSE file for details
|
|
|
|
## Credits
|
|
|
|
Inspired by [Prosody XMPP Server](https://prosody.im/) written in Lua.
|
|
|
|
## Support
|
|
|
|
- Documentation: [docs/](docs/)
|
|
- Issues: GitHub Issues
|
|
- Community: XMPP MUC at prosody-nodejs@conference.example.com
|
|
|
|
## Roadmap
|
|
|
|
### Version 1.0
|
|
- [x] Core XMPP protocol
|
|
- [x] C2S connections
|
|
- [x] Basic authentication
|
|
- [x] 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
|
|
|
|
```javascript
|
|
// 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](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.
|
|
|
|
## References
|
|
|
|
- [XMPP Standards Foundation](https://xmpp.org/)
|
|
- [RFC 6120 - XMPP Core](https://tools.ietf.org/html/rfc6120)
|
|
- [RFC 6121 - XMPP IM](https://tools.ietf.org/html/rfc6121)
|
|
- [Prosody Documentation](https://prosody.im/doc/)
|