481
README.md
Archivo normal
481
README.md
Archivo normal
@@ -0,0 +1,481 @@
|
||||
# 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/)
|
||||
Referencia en una nueva incidencia
Block a user