# 🧅 Bloodweb Onion Chat

Anonymous, encrypted chat service accessible via Tor network. Standalone service with zero integration into main bloodweb infrastructure - isolated by design for maximum security and privacy.

## 🎯 Features

- **Full Anonymity**: Tor Browser detection with mandatory access warning
- **Zero Logging**: No IP addresses, no tracking, no surveillance
- **Ephemeral Messages**: Auto-expire after 24 hours
- **Client-Side Encryption Ready**: Architecture supports end-to-end encryption
- **Isolated Infrastructure**: Separate database, no bloodweb MySQL dependencies
- **Real-Time Chat**: WebSocket-based instant messaging
- **Session-Based Identity**: Anonymous usernames with optional customization

## 📁 Project Structure

```
onion/
├── config/
│   ├── nginx.conf.example      # Reverse proxy configuration
│   └── torrc.example           # Tor hidden service configuration
├── public/
│   ├── index.html              # Chat interface (vanilla JS)
│   └── tor-required.html       # Warning page for non-Tor browsers
├── server/
│   └── index.js                # Node.js + Socket.io + SQLite server
├── data/                       # Created at runtime
│   └── chat.db                 # SQLite database (auto-created)
├── package.json
└── README.md
```

## 🚀 Quick Start

### Prerequisites

- Node.js 18+ 
- Tor (for hidden service)
- Nginx (for clearnet proxy - optional)

### 1. Install Dependencies

```bash
cd /var/www/html/onion
npm install
```

### 2. Create Data Directory

```bash
mkdir -p data
chmod 700 data
```

### 3. Start the Chat Server

```bash
# Development mode (with auto-reload)
npm run dev

# Production mode
npm start
```

Server runs on `http://127.0.0.1:3000`

### 4. Configure Tor Hidden Service

```bash
# Copy Tor configuration
sudo cp config/torrc.example /etc/tor/torrc
# Or append to existing torrc

# Restart Tor
sudo systemctl restart tor

# Get your .onion address
sudo cat /var/lib/tor/bloodweb-onion-chat/hostname
```

**Example .onion address:**
```
abcd1234efgh5678ijklmnop9012qrst3456uvwxyz7890abcdefghij.onion
```

### 5. Update Warning Page with .onion Address

Edit `public/tor-required.html` and update the onion address:

```html
<div class="onion-address" id="onion-address">
    http://[YOUR-ONION-ADDRESS].onion
</div>
```

### 6. (Optional) Configure Nginx for Clearnet Access

```bash
# Copy nginx config
sudo cp config/nginx.conf.example /etc/nginx/sites-available/onion.bloodweb.net

# Enable site
sudo ln -s /etc/nginx/sites-available/onion.bloodweb.net /etc/nginx/sites-enabled/

# Get SSL certificate
sudo certbot --nginx -d onion.bloodweb.net

# Test and reload
sudo nginx -t
sudo systemctl reload nginx
```

## 🔧 Production Setup

### Systemd Service (Auto-Start)

Create `/etc/systemd/system/bloodweb-onion-chat.service`:

```ini
[Unit]
Description=Bloodweb Onion Chat Service
After=network.target tor.service

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/html/onion
ExecStart=/usr/bin/node server/index.js
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=onion-chat

# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/www/html/onion/data

[Install]
WantedBy=multi-user.target
```

**Enable and start:**

```bash
sudo systemctl daemon-reload
sudo systemctl enable bloodweb-onion-chat
sudo systemctl start bloodweb-onion-chat
sudo systemctl status bloodweb-onion-chat
```

### View Logs

```bash
# Application logs
sudo journalctl -u bloodweb-onion-chat -f

# Nginx logs
sudo tail -f /var/log/nginx/onion.bloodweb.net.access.log
sudo tail -f /var/log/nginx/onion.bloodweb.net.error.log

# Tor logs
sudo tail -f /var/log/tor/notices.log
```

## 🔒 Security Architecture

### Isolation Strategy

1. **Separate Database**: SQLite file isolated from bloodweb MySQL
2. **No Shared Credentials**: Zero access to bloodweb databases
3. **Independent Process**: Runs as separate Node.js service
4. **Firewall Isolation**: Only localhost:3000 exposed to Nginx/Tor
5. **No Cross-Origin Requests**: Strict CORS policy

### Tor Browser Detection

Server-side checks:
- User-Agent header for "Tor Browser" string
- `.onion` domain detection
- `X-Tor2Web` header presence

Bypass mechanism:
- 1-hour cookie: `tor_bypass=accepted`
- Strong warning about anonymity risks
- Only available via clearnet access

### Data Retention

- Messages expire after **24 hours**
- Inactive users removed after **5 minutes**
- No IP addresses stored
- No browser fingerprinting
- Automatic cleanup runs hourly

### Security Headers

All enforced via Helmet.js and Nginx:

```
Content-Security-Policy: default-src 'self'
X-Frame-Options: DENY
Referrer-Policy: no-referrer
X-Content-Type-Options: nosniff
```

## 🛠️ Development

### Environment Variables

```bash
# .env file (optional)
PORT=3000
MESSAGE_TTL_HOURS=24
NODE_ENV=production
```

### Database Schema

```sql
-- Messages table
CREATE TABLE messages (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    session_id TEXT NOT NULL,
    username TEXT NOT NULL,
    message TEXT NOT NULL,
    timestamp INTEGER NOT NULL,
    expires_at INTEGER NOT NULL
);

-- Active users table
CREATE TABLE active_users (
    session_id TEXT PRIMARY KEY,
    username TEXT NOT NULL,
    last_seen INTEGER NOT NULL,
    is_authenticated BOOLEAN DEFAULT 0
);
```

### API Endpoints

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/` | GET | Chat interface (with Tor check) |
| `/tor-required.html` | GET | Warning page |
| `/health` | GET | Health check |
| `/api/messages` | GET | Recent messages (last 50) |

### WebSocket Events

**Client → Server:**
- `join` - Join chat with username
- `message` - Send chat message
- `typing` - Typing indicator

**Server → Client:**
- `joined` - Join confirmation
- `message` - New message broadcast
- `user_joined` - User join notification
- `user_left` - User leave notification
- `user_count` - Active user count update
- `user_typing` - Someone is typing
- `error` - Error message

## 📊 Monitoring

### Health Check

```bash
curl http://127.0.0.1:3000/health
```

Response:
```json
{
  "status": "healthy",
  "timestamp": 1707926400000,
  "activeUsers": 5,
  "messageCount": 127
}
```

### Database Maintenance

```bash
# Check database size
ls -lh data/chat.db

# Manual cleanup (if needed)
sqlite3 data/chat.db "DELETE FROM messages WHERE expires_at < $(date +%s)000;"
sqlite3 data/chat.db "VACUUM;"
```

## 🚨 Troubleshooting

### Chat won't load in Tor Browser

1. Check if server is running: `sudo systemctl status bloodweb-onion-chat`
2. Verify Tor service: `sudo systemctl status tor`
3. Confirm .onion address: `sudo cat /var/lib/tor/bloodweb-onion-chat/hostname`
4. Check Tor logs: `sudo tail -f /var/log/tor/notices.log`

### WebSocket connection fails

1. Check Socket.io is loaded: View browser console for errors
2. Verify port 3000 is accessible: `curl http://127.0.0.1:3000/health`
3. Nginx WebSocket proxy: Check `proxy_set_header Upgrade` configuration
4. Firewall rules: Ensure localhost can connect to 3000

### "Tor Browser Required" page always shows

1. Check User-Agent string in browser dev tools
2. Verify bypass cookie if using clearnet: Check cookies for `tor_bypass`
3. Confirm .onion access directly via Tor Browser
4. Check server logs for detection logic

### Messages not persisting

1. Check data directory permissions: `ls -la data/`
2. Verify SQLite file exists: `ls -lh data/chat.db`
3. Check disk space: `df -h`
4. Review application logs for database errors

## 🔐 Backup & Recovery

### Critical Files to Backup

```bash
# Tor hidden service identity (DO NOT LOSE!)
/var/lib/tor/bloodweb-onion-chat/hostname
/var/lib/tor/bloodweb-onion-chat/hs_ed25519_secret_key
/var/lib/tor/bloodweb-onion-chat/hs_ed25519_public_key

# Chat database (optional - messages expire anyway)
/var/www/html/onion/data/chat.db
```

**Backup script:**

```bash
#!/bin/bash
BACKUP_DIR="/var/backups/onion-chat"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p "$BACKUP_DIR"

# Backup Tor keys
sudo tar -czf "$BACKUP_DIR/tor-keys-$DATE.tar.gz" \
    /var/lib/tor/bloodweb-onion-chat/

# Backup database
cp data/chat.db "$BACKUP_DIR/chat-db-$DATE.db"

# Keep only last 7 backups
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete
find "$BACKUP_DIR" -name "*.db" -mtime +7 -delete
```

## 📚 Future Enhancements

- [ ] End-to-end encryption (Signal Protocol / libsodium.js)
- [ ] File sharing with ephemeral storage
- [ ] Private rooms / DMs
- [ ] Authenticated bloodweb user badges (optional)
- [ ] Message reactions and threading
- [ ] Voice/video chat via WebRTC
- [ ] Mobile-optimized PWA
- [ ] Rate limiting per session
- [ ] Admin moderation panel

## ⚖️ Legal & Ethics

**This service is designed for:**
- Privacy-conscious communication
- Whistleblower protection
- Journalistic sources
- Anonymous support groups
- Research and development

**Not intended for:**
- Illegal activity
- Harassment or abuse
- CSAM or illegal content
- Coordinating crimes

**Operator responsibilities:**
- No logs = No liability for content (generally)
- Comply with local laws regarding anonymous services
- Consider terms of service and acceptable use policy
- Monitor for abuse (if legally required)

## 📞 Support

For issues specific to this service:
- Check logs first: `sudo journalctl -u bloodweb-onion-chat -f`
- Review this README thoroughly
- Test in isolation: `npm start` directly

For bloodweb.net integration questions:
- Contact: jack@bloodweb.net
- Documentation: /docs/

## 📄 License

UNLICENSED - Part of the Bloodweb project.
© 2026 Jack Ewers / bloodweb.net

---

**⚠️ SECURITY NOTICE**: This is a Tor hidden service. The server operator cannot see user IP addresses when accessed via .onion. Clearnet access (onion.bloodweb.net) exposes your IP to the server. Always use Tor Browser for true anonymity.
