# ProtonBridge Email Setup for Tractatus ## Overview Tractatus uses **ProtonBridge** for email sending, replicating the proven architecture from the family-history project. ProtonBridge runs as a systemd service on the production VPS, providing localhost SMTP/IMAP access to your Proton account. **Status**: Proven architecture (validated in family-history production: 3+ months uptime, 315+ app restarts, zero email disruptions as of 2025-11-03) --- ## Architecture ``` ┌─────────────────────────────────────────────────┐ │ Tractatus Application (Node.js) │ │ ├─ Email Service (Nodemailer) │ │ └─ Connects to: localhost:1026 (SMTP) │ └─────────────────┬───────────────────────────────┘ │ │ TCP Connection │ ┌─────────────────▼───────────────────────────────┐ │ ProtonBridge (Systemd Service) │ │ ├─ Listens on: 127.0.0.1:1026 (prod) │ │ ├─ Auth: Bridge-generated password │ │ └─ Connects to: ProtonMail servers │ └─────────────────┬───────────────────────────────┘ │ │ TLS/HTTPS │ ┌─────────────────▼───────────────────────────────┐ │ ProtonMail Servers │ │ └─ Actual email delivery │ └─────────────────────────────────────────────────┘ ``` --- ## Part 1: VPS Setup (One-time Configuration) ### Prerequisites - Ubuntu 22.04 LTS VPS (already configured) - Paid Proton account - SSH access to production server: `vps-93a693da.vps.ovh.net` ### Step 1: Install ProtonBridge on VPS ```bash # SSH to production server ssh -i ~/.ssh/tractatus_deploy ubuntu@vps-93a693da.vps.ovh.net # Install dependencies sudo apt-get update sudo apt-get install -y pass gnupg xvfb # Download ProtonBridge (check for latest version) wget https://proton.me/download/bridge/protonmail-bridge_3.0.21-1_amd64.deb sudo dpkg -i protonmail-bridge_3.0.21-1_amd64.deb sudo apt-get install -f # Fix any dependency issues ``` ### Step 2: Configure GPG and Pass ```bash # Generate GPG key (for pass credential manager) gpg --gen-key # - Use real name and email # - Choose strong passphrase # - Save the key ID shown # Initialize pass with your GPG key ID pass init "YOUR_GPG_KEY_ID" ``` ### Step 3: Configure ProtonBridge ```bash # Run ProtonBridge interactively (first time only) protonmail-bridge --cli # In ProtonBridge CLI: > login # Enter your Proton account credentials > info # IMPORTANT: Copy the Bridge password shown (different from Proton password) # Example: cETwrBktTQMBQrMddzCFIg # This is what SMTP_PASS will be > exit ``` ### Step 4: Create ProtonBridge Systemd Service Create service file: ```bash sudo nano /etc/systemd/system/protonmail-bridge.service ``` **Paste this configuration:** ```ini [Unit] Description=ProtonMail Bridge After=network.target [Service] Type=simple User=ubuntu WorkingDirectory=/home/ubuntu Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" Environment="HOME=/home/ubuntu" Environment="DISPLAY=:99" Environment="DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus" Environment="XDG_RUNTIME_DIR=/run/user/1000" ExecStartPre=/bin/bash -c 'if ! pgrep -x "Xvfb" > /dev/null; then Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & fi' ExecStart=/usr/bin/protonmail-bridge --noninteractive Restart=always RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target ``` **Enable and start the service:** ```bash # Reload systemd sudo systemctl daemon-reload # Enable for auto-start on boot sudo systemctl enable protonmail-bridge # Start the service sudo systemctl start protonmail-bridge # Check status sudo systemctl status protonmail-bridge # Should show: "active (running)" ``` ### Step 5: Verify ProtonBridge Ports ```bash # Test SMTP port (should connect) nc -zv 127.0.0.1 1026 # Test IMAP port (should connect) nc -zv 127.0.0.1 1144 # View ProtonBridge logs sudo journalctl -u protonmail-bridge -f ``` --- ## Part 2: Tractatus Application Configuration ### Environment Variables (Production) **File**: `/var/www/tractatus/.env` (on production server) Add these variables: ```bash # Email Service Configuration EMAIL_ENABLED=true EMAIL_PROVIDER=proton # SMTP Configuration (ProtonBridge) SMTP_HOST=127.0.0.1 SMTP_PORT=1026 # Production port SMTP_SECURE=false # localhost doesn't need TLS SMTP_USER=your-tractatus-email@pm.me # Your Proton email SMTP_PASS=YOUR_BRIDGE_PASSWORD # From ProtonBridge setup (Step 3) EMAIL_FROM=your-tractatus-email@pm.me # Newsletter URLs NEWSLETTER_UNSUBSCRIBE_BASE_URL=https://agenticgovernance.digital/api/newsletter/unsubscribe NEWSLETTER_PREFERENCES_BASE_URL=https://agenticgovernance.digital/newsletter/preferences ``` ### Environment Variables (Development) **File**: `/home/theflow/projects/tractatus/.env` (local dev machine) ```bash # Email Service Configuration (DISABLED in dev) EMAIL_ENABLED=false # Optional: If you want to test locally with ProtonBridge # SMTP_HOST=127.0.0.1 # SMTP_PORT=1025 # Development port # SMTP_USER=your-email@pm.me # SMTP_PASS=YOUR_BRIDGE_PASSWORD ``` --- ## Part 3: Production Deployment Script The existing `deploy.sh` script will handle deployment. ProtonBridge configuration is managed via `.env` on the production server. ### Manual Deployment Steps (if needed) ```bash # From local machine cd /home/theflow/projects/tractatus # Deploy email service changes ./scripts/deploy.sh src/services/email.service.js --restart # Or full deployment ./scripts/deploy.sh ``` --- ## Part 4: Testing & Verification ### Test 1: Check ProtonBridge Status ```bash # On production server sudo systemctl status protonmail-bridge # Should show: # Active: active (running) since... # Uptime: X days ``` ### Test 2: Test SMTP Connection ```bash # On production server telnet 127.0.0.1 1026 # Should connect successfully # Type QUIT to exit ``` ### Test 3: Test Email Sending (Node.js) ```bash # On production server cd /var/www/tractatus # Quick test script node -e " const nodemailer = require('nodemailer'); const transporter = nodemailer.createTransport({ host: '127.0.0.1', port: 1026, secure: false, auth: { user: 'your-email@pm.me', pass: 'YOUR_BRIDGE_PASSWORD' }, tls: { rejectUnauthorized: false } }); transporter.sendMail({ from: 'your-email@pm.me', to: 'test@example.com', subject: 'ProtonBridge Test', text: 'Test email from Tractatus' }, (err, info) => { if (err) { console.error('Error:', err); } else { console.log('Success! Message ID:', info.messageId); } process.exit(err ? 1 : 0); }); " ``` ### Test 4: Check Application Health ```bash # Test health endpoint curl -s https://agenticgovernance.digital/health/detailed | jq '.services.email' # Should show: # { # "status": "running", # "smtp": { # "status": "connected", # "host": "127.0.0.1", # "port": "1026" # } # } ``` ### Test 5: Send Test Newsletter 1. Access newsletter administration interface (admin authentication required) 2. Fill in newsletter form (use JSON for content) 3. Click "Send Test" button 4. Enter your email address 5. Check inbox for test email --- ## Monitoring & Maintenance ### View ProtonBridge Logs ```bash # Real-time logs sudo journalctl -u protonmail-bridge -f # Last 50 lines sudo journalctl -u protonmail-bridge -n 50 # Logs from specific date sudo journalctl -u protonmail-bridge --since "2025-11-03" ``` ### View Application Email Logs ```bash # Tractatus uses systemd service sudo journalctl -u tractatus -f | grep EmailService # Or check PM2 logs (if using PM2) pm2 logs tractatus-prod | grep EmailService ``` ### Restart Services ```bash # Restart ProtonBridge (rarely needed) sudo systemctl restart protonmail-bridge # Restart Tractatus application sudo systemctl restart tractatus ``` ### Health Check Commands ```bash # Check ProtonBridge is listening ss -tuln | grep -E '1026|1144' # Check application connection curl -s http://localhost:9000/health/detailed | jq . # Test SMTP auth nc -zv 127.0.0.1 1026 ``` --- ## Troubleshooting ### Problem: "SMTP connection verification failed" **Cause**: ProtonBridge not running or not fully synced **Solution**: ```bash # Check ProtonBridge status sudo systemctl status protonmail-bridge # Check if ports are listening ss -tuln | grep 1026 # Restart ProtonBridge sudo systemctl restart protonmail-bridge # Wait 30 seconds for mailbox sync sleep 30 # Restart application sudo systemctl restart tractatus ``` ### Problem: "Authentication failed" **Cause**: Incorrect Bridge password (not Proton account password) **Solution**: ```bash # Get correct Bridge password protonmail-bridge --cli > info > exit # Update .env with correct SMTP_PASS nano /var/www/tractatus/.env # Restart application sudo systemctl restart tractatus ``` ### Problem: Email sending works but emails not received **Cause**: SPF/DKIM records not configured **Solution**: ProtonMail handles SPF/DKIM automatically - no DNS changes needed. Check spam folder. ### Problem: ProtonBridge keeps restarting **Cause**: GPG/pass configuration issue **Solution**: ```bash # Check GPG keys gpg --list-keys # Reinitialize pass if needed pass init "YOUR_GPG_KEY_ID" # Reconfigure ProtonBridge protonmail-bridge --cli > login > info > exit ``` --- ## Port Reference | Service | Environment | Port | Protocol | |---------|-------------|------|----------| | ProtonBridge SMTP | Production | 1026 | STARTTLS | | ProtonBridge SMTP | Development | 1025 | STARTTLS | | ProtonBridge IMAP | Production | 1144 | STARTTLS | | ProtonBridge IMAP | Development | 1143 | STARTTLS | **Note**: Tractatus EmailService automatically detects production vs development and uses the correct port. --- ## Security Considerations 1. **Localhost Only**: ProtonBridge only binds to 127.0.0.1 - not accessible externally 2. **No TLS Needed**: Localhost connections are secure without TLS 3. **Bridge Password**: Different from Proton account credentials (generated by ProtonBridge) 4. **Email Disabled in Dev**: Prevents accidental email sends during development 5. **Rate Limiting**: EmailService enforces 10 emails/second max 6. **Connection Pooling**: Reuses connections for efficiency --- ## Comparison: ProtonBridge vs SendGrid | Feature | ProtonBridge | SendGrid | |---------|-------------|----------| | **Cost** | Paid Proton account (~$4/month) | Free: 100/day, Paid: $19.95/month | | **Privacy** | End-to-end encrypted | Third-party data access | | **Deliverability** | Good (uses Proton infrastructure) | Excellent (dedicated IPs, reputation) | | **Setup Complexity** | Moderate (requires VPS setup) | Easy (API key only) | | **Sending Limits** | 1,000/day (Proton paid) | 50,000/month (paid tier) | | **Control** | Self-hosted bridge | Cloud service | | **Reliability** | Depends on VPS uptime | 99.9% SLA | --- ## Migration from SendGrid Already completed! The changes include: 1. ✅ Replaced `@sendgrid/mail` with `nodemailer` 2. ✅ Updated EmailService with ProtonBridge configuration 3. ✅ Added smart port detection (prod vs dev) 4. ✅ Implemented connection pooling and rate limiting 5. ✅ Added EMAIL_ENABLED flag for dev/prod separation No API changes - existing newsletter functionality works identically. --- ## Next Steps 1. **Install ProtonBridge on production server** (Part 1) 2. **Update production .env** with Bridge credentials (Part 2) 3. **Deploy updated EmailService** (Part 3) 4. **Test email sending** (Part 4) 5. **Monitor for 24 hours** to ensure stability --- ## Support & Resources - **ProtonBridge Documentation**: https://proton.me/support/protonmail-bridge-install - **Nodemailer Documentation**: https://nodemailer.com/ - **Family-History Reference**: `/home/theflow/projects/family-history/src/services/emailService.js` - **Tractatus Email Service**: `/home/theflow/projects/tractatus/src/services/email.service.js` --- **Last Updated**: 2025-11-03 **Architecture Version**: 1.0 (based on family-history production setup)