A utility to back up mail from various sources to couchdb
Find a file
Ole-Morten Duesund 8764b44a05 feat: implement comprehensive environment variable credential support
- Add environment variable overrides for sensitive credentials in both Go and Rust implementations
- Support MAIL2COUCH_COUCHDB_USER and MAIL2COUCH_COUCHDB_PASSWORD for CouchDB credentials
- Support MAIL2COUCH_IMAP_<NAME>_USER and MAIL2COUCH_IMAP_<NAME>_PASSWORD for IMAP credentials
- Implement automatic name normalization for mail source names to environment variable format
- Add runtime display of active environment variable overrides
- Enhance --help output in both implementations with comprehensive environment variable documentation
- Add detailed environment variable section to README with usage examples and security benefits
- Create comprehensive ENVIRONMENT_VARIABLES.md reference guide with SystemD, Docker, and CI/CD examples
- Update all documentation indices and cross-references
- Include security best practices and troubleshooting guidance
- Maintain full backward compatibility with existing configuration files

This enhancement addresses the high-priority security requirement to eliminate plaintext
passwords from configuration files while providing production-ready credential management
for both development and deployment scenarios.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-07 15:09:34 +02:00
docs feat: implement comprehensive environment variable credential support 2025-08-07 15:09:34 +02:00
go feat: implement comprehensive environment variable credential support 2025-08-07 15:09:34 +02:00
rust feat: implement comprehensive environment variable credential support 2025-08-07 15:09:34 +02:00
scripts docs: add comprehensive CouchDB schema documentation for cross-implementation compatibility 2025-08-02 15:08:35 +02:00
systemd feat: add systemd user services and timer units 2025-08-03 23:59:34 +02:00
test feat: implement GNU-style command line options with pflag 2025-08-02 15:17:04 +02:00
.gitignore refactor: remove webmail interface, focus on core mail storage functionality 2025-08-02 14:57:51 +02:00
CLAUDE.md feat: improve installation system with user-local and system-wide options 2025-08-03 19:05:30 +02:00
config-advanced.json feat: add comprehensive README documentation and clean up configuration 2025-08-01 21:26:53 +02:00
config-providers.json feat: add comprehensive README documentation and clean up configuration 2025-08-01 21:26:53 +02:00
config-simple.json feat: add comprehensive README documentation and clean up configuration 2025-08-01 21:26:53 +02:00
config.json feat: add comprehensive README documentation and clean up configuration 2025-08-01 21:26:53 +02:00
justfile feat: add systemd user services and timer units 2025-08-03 23:59:34 +02:00
LICENSE feat: add MIT license 2025-08-02 15:32:47 +02:00
README.md feat: implement comprehensive environment variable credential support 2025-08-07 15:09:34 +02:00
test-both-implementations.sh feat: complete code formatting and linting compliance 2025-08-05 19:20:22 +02:00
test-config-go.json fix: correct duplicate message reporting in Go implementation 2025-08-04 00:36:01 +02:00
test-config-rust.json fix: correct duplicate message reporting in Go implementation 2025-08-04 00:36:01 +02:00
test-config-shared.json fix: correct duplicate message reporting in Go implementation 2025-08-04 00:36:01 +02:00
test-incremental-config.json fix: correct duplicate message reporting in Go implementation 2025-08-04 00:36:01 +02:00

mail2couch

A powerful email backup utility that synchronizes mail from IMAP accounts to CouchDB databases with intelligent incremental sync, comprehensive filtering, and native attachment support.

Features

Core Functionality

  • IMAP Email Backup: Connect to any IMAP server (Gmail, Outlook, self-hosted)
  • CouchDB Storage: Store emails as JSON documents with native CouchDB attachments
  • Incremental Sync: Efficiently sync only new messages using IMAP SEARCH with timestamp tracking
  • Per-Account Databases: Each mail source gets its own CouchDB database for better organization
  • Duplicate Prevention: Automatic detection and prevention of duplicate message storage

Sync Modes

  • Archive Mode: Preserve all messages ever seen, even if deleted from mail server (default)
  • Sync Mode: Maintain 1-to-1 relationship with mail server (removes deleted messages from CouchDB)

Advanced Filtering

  • Wildcard Folder Patterns: Use *, ?, [abc] patterns for flexible folder selection
  • Keyword Filtering: Filter messages by keywords in subjects, senders, or recipients
  • Date Filtering: Process only messages since a specific date
  • Include/Exclude Logic: Combine multiple filter types for precise control

Message Processing

  • Full MIME Support: Parse multipart messages, HTML/plain text, and embedded content
  • Native Attachments: Store email attachments as CouchDB native attachments with compression
  • Complete Headers: Preserve all email headers and metadata
  • UTF-8 Support: Handle international characters and special content

HTML Webmail Interface

  • Beautiful Web Interface: Modern, responsive HTML presentations for viewing archived emails
  • Gmail-like Design: Professional, mobile-friendly interface with clean typography
  • Message Lists: Dynamic HTML lists with sorting, filtering, and folder organization
  • Individual Messages: Rich HTML display with proper formatting, URL linking, and collapsible headers
  • Attachment Support: Direct download links with file type and size information
  • Search Integration: Full-text subject search with keyword highlighting
  • Folder Analytics: Message count summaries and folder-based navigation
  • Mobile Responsive: Optimized for desktop, tablet, and mobile viewing

Operational Features

  • Automatic Config Discovery: Finds configuration files in standard locations
  • Command Line Control: GNU-style options with --max-messages/-m and --config/-c flags
  • Comprehensive Logging: Detailed output for monitoring and troubleshooting
  • Error Resilience: Graceful handling of network issues and server problems

Project Status

Production Ready (August 2025): Both Go and Rust implementations are fully functional with identical feature sets and database output.

  • Complete Feature Parity: Server-side filtering, binary attachments, incremental sync
  • Comprehensive Testing: Verified identical CouchDB output between implementations
  • SystemD Integration: Automated scheduling with timer units
  • Production Quality: Robust error handling, retry logic, dry-run mode

📚 Documentation

Comprehensive documentation is available in the docs/ directory:

Quick Start

Installation

  1. Install dependencies:

    # Go 1.21+ required
    go version
    
  2. Clone and build:

    git clone <repository-url>
    cd mail2couch/go
    go build -o mail2couch .
    

Basic Usage

  1. Create configuration file (config.json):

    {
      "couchDb": {
        "url": "http://localhost:5984",
        "user": "admin", 
        "password": "password"
      },
      "mailSources": [
        {
          "name": "Personal Gmail",
          "enabled": true,
          "protocol": "imap",
          "host": "imap.gmail.com",
          "port": 993,
          "user": "your-email@gmail.com",
          "password": "your-app-password",
          "mode": "archive",
          "folderFilter": {
            "include": ["*"],
            "exclude": ["[Gmail]/Trash", "[Gmail]/Spam"]
          }
        }
      ]
    }
    
  2. Run mail2couch:

    ./mail2couch
    

The application will:

  • Create a CouchDB database named m2c_personal_gmail
  • Sync all folders except Trash and Spam
  • Store messages with native attachments
  • Track sync state for efficient incremental updates

Configuration

Configuration File Discovery

mail2couch automatically searches for configuration files in this order:

  1. Path specified by --config/-c flag
  2. ./config.json (current directory)
  3. ./config/config.json (config subdirectory)
  4. ~/.config/mail2couch/config.json (user config directory)
  5. ~/.mail2couch.json (user home directory)

Command Line Options

./mail2couch [options]

Options:
  -c, --config FILE        Path to configuration file
  -m, --max-messages N     Limit messages processed per mailbox per run (0 = unlimited)
  -n, --dry-run            Show what would be done without making changes
  -h, --help               Show help message

Environment Variables

mail2couch supports environment variable overrides for sensitive credentials, allowing you to keep passwords out of configuration files:

Environment Variable Purpose Example
MAIL2COUCH_COUCHDB_USER Override CouchDB username admin
MAIL2COUCH_COUCHDB_PASSWORD Override CouchDB password secure_password
MAIL2COUCH_IMAP_<NAME>_USER Override IMAP username for source <NAME> user@gmail.com
MAIL2COUCH_IMAP_<NAME>_PASSWORD Override IMAP password for source <NAME> app_password

Name Normalization: The <NAME> part is the mail source name from your configuration converted to uppercase with non-alphanumeric characters replaced by underscores.

Examples:

  • Source name "Personal Gmail"MAIL2COUCH_IMAP_PERSONAL_GMAIL_PASSWORD
  • Source name "Work Email"MAIL2COUCH_IMAP_WORK_EMAIL_USER
  • Source name "Self-Hosted Mail"MAIL2COUCH_IMAP_SELF_HOSTED_MAIL_PASSWORD

Usage Examples:

# Override CouchDB credentials
MAIL2COUCH_COUCHDB_PASSWORD=secret ./mail2couch

# Override IMAP password for a specific account
MAIL2COUCH_IMAP_PERSONAL_GMAIL_PASSWORD=app-password ./mail2couch

# Use with systemd service (in service file)
Environment="MAIL2COUCH_COUCHDB_PASSWORD=secret"
Environment="MAIL2COUCH_IMAP_WORK_EMAIL_PASSWORD=app-pass"

# Combine with other options
MAIL2COUCH_COUCHDB_USER=backup_user ./mail2couch --dry-run --max-messages 100

Security Benefits:

  • Keep sensitive credentials out of configuration files
  • Use different credentials per environment (dev/staging/prod)
  • Integrate with CI/CD systems and secret management
  • Maintain backward compatibility with existing configurations

Folder Pattern Examples

Pattern Description Matches
"*" All folders INBOX, Sent, Work/Projects, etc.
"INBOX" Exact match INBOX only
"Work*" Prefix match Work, Work/Projects, WorkStuff
"*/Archive" Suffix match Personal/Archive, Work/Archive
"Work/*" Subfolder match Work/Projects, Work/Clients

Keyword Filtering Examples

{
  "messageFilter": {
    "subjectKeywords": ["urgent", "meeting", "invoice"],
    "senderKeywords": ["@company.com", "noreply@"],
    "recipientKeywords": ["team@", "support@"]
  }
}

Advanced Configuration Examples

See the example configurations section below for detailed configuration scenarios.

Testing

A comprehensive test environment is included with Podman containers:

cd test

# Quick automated testing (recommended)
./run-tests.sh              # Complete integration test with automatic cleanup

# Specialized feature testing  
./test-wildcard-patterns.sh # Test folder pattern matching
./test-incremental-sync.sh  # Test incremental synchronization

# Manual testing environment
./start-test-env.sh         # Start persistent test environment
# ... manual testing with various configurations ...
./stop-test-env.sh          # Clean up when done

Architecture

Database Structure

  • Per-Account Databases: Each mail source creates its own CouchDB database with m2c_ prefix
  • Message Documents: Each email becomes a CouchDB document with metadata
  • Native Attachments: Email attachments stored as CouchDB attachments (compressed)
  • Sync Metadata: Tracks incremental sync state per mailbox
  • HTML Webmail Views: CouchDB design documents with show/list functions for web interface

Document Structure

{
  "_id": "INBOX_12345",
  "sourceUid": "12345", 
  "mailbox": "INBOX",
  "from": ["sender@example.com"],
  "to": ["recipient@example.com"],
  "subject": "Sample Email",
  "date": "2024-01-15T10:30:00Z",
  "body": "Email content...",
  "headers": {"Content-Type": ["text/plain"]},
  "storedAt": "2024-01-15T10:35:00Z",
  "docType": "mail",
  "hasAttachments": true,
  "_attachments": {
    "document.pdf": {
      "content_type": "application/pdf",
      "length": 54321
    }
  }
}

Accessing Stored Emails

Once mail2couch has synced your emails, you can access them through CouchDB's REST API:

Raw Data Access

# List all databases
http://localhost:5984/_all_dbs

# View database info
http://localhost:5984/{database}

# List all documents in database  
http://localhost:5984/{database}/_all_docs

# Get individual message
http://localhost:5984/{database}/{message_id}

# Get message with attachments
http://localhost:5984/{database}/{message_id}/{attachment_name}

Example Configurations

Simple Configuration

Basic setup for a single Gmail account:

{
  "couchDb": {
    "url": "http://localhost:5984",
    "user": "admin",
    "password": "password"
  },
  "mailSources": [
    {
      "name": "Personal Gmail",
      "enabled": true,
      "protocol": "imap",
      "host": "imap.gmail.com", 
      "port": 993,
      "user": "your-email@gmail.com",
      "password": "your-app-password",
      "mode": "archive",
      "folderFilter": {
        "include": ["INBOX", "Sent"],
        "exclude": []
      },
      "messageFilter": {
        "since": "2024-01-01"
      }
    }
  ]
}

Secure Configuration with Environment Variables

Configuration using placeholder values with sensitive credentials provided via environment variables:

{
  "couchDb": {
    "url": "http://localhost:5984",
    "user": "placeholder",
    "password": "placeholder"
  },
  "mailSources": [
    {
      "name": "Personal Gmail",
      "enabled": true,
      "protocol": "imap",
      "host": "imap.gmail.com",
      "port": 993,
      "user": "placeholder",
      "password": "placeholder",
      "mode": "archive",
      "folderFilter": {
        "include": ["INBOX", "Sent"],
        "exclude": []
      }
    }
  ]
}

Run with environment variables:

# Set credentials via environment variables
export MAIL2COUCH_COUCHDB_USER="admin"
export MAIL2COUCH_COUCHDB_PASSWORD="secure_couchdb_password"
export MAIL2COUCH_IMAP_PERSONAL_GMAIL_USER="your-email@gmail.com"
export MAIL2COUCH_IMAP_PERSONAL_GMAIL_PASSWORD="your-app-password"

# Run mail2couch (credentials will override config placeholders)
./mail2couch

Advanced Multi-Account Configuration

Complex setup with multiple accounts, filtering, and different sync modes:

{
  "couchDb": {
    "url": "https://your-couchdb.example.com:5984",
    "user": "backup_user",
    "password": "secure_password"
  },
  "mailSources": [
    {
      "name": "Work Email", 
      "enabled": true,
      "protocol": "imap",
      "host": "outlook.office365.com",
      "port": 993,
      "user": "you@company.com",
      "password": "app-password",
      "mode": "sync",
      "folderFilter": {
        "include": ["*"],
        "exclude": ["Deleted Items", "Junk Email", "Drafts"]
      },
      "messageFilter": {
        "since": "2023-01-01",
        "subjectKeywords": ["project", "meeting", "urgent"],
        "senderKeywords": ["@company.com", "@client.com"]
      }
    },
    {
      "name": "Personal Gmail",
      "enabled": true, 
      "protocol": "imap",
      "host": "imap.gmail.com",
      "port": 993,
      "user": "personal@gmail.com",
      "password": "gmail-app-password",
      "mode": "archive",
      "folderFilter": {
        "include": ["INBOX", "Important", "Work/*", "Personal/*"],
        "exclude": ["[Gmail]/Trash", "[Gmail]/Spam", "*Temp*"]
      },
      "messageFilter": {
        "recipientKeywords": ["family@", "personal@"]
      }
    },
    {
      "name": "Self-Hosted Mail",
      "enabled": true,
      "protocol": "imap", 
      "host": "mail.yourdomain.com",
      "port": 143,
      "user": "admin@yourdomain.com",
      "password": "mail-password",
      "mode": "archive",
      "folderFilter": {
        "include": ["INBOX", "Archive/*", "Projects/*"],
        "exclude": ["*/Drafts", "Trash"]
      },
      "messageFilter": {
        "since": "2023-06-01",
        "subjectKeywords": ["invoice", "receipt", "statement"]
      }
    },
    {
      "name": "Legacy Account",
      "enabled": false,
      "protocol": "imap",
      "host": "legacy.mailserver.com", 
      "port": 993,
      "user": "old@account.com",
      "password": "legacy-password",
      "mode": "archive",
      "folderFilter": {
        "include": ["INBOX"],
        "exclude": []
      },
      "messageFilter": {}
    }
  ]
}

Configuration Options Reference

CouchDB Configuration

  • url: CouchDB server URL with protocol and port
  • user: CouchDB username with database access
  • password: CouchDB password

Mail Source Configuration

  • name: Descriptive name (used for database naming)
  • enabled: Boolean to enable/disable this source
  • protocol: Only "imap" currently supported
  • host: IMAP server hostname
  • port: IMAP port (993 for TLS, 143 for plain, 3143 for testing)
  • user: Email account username
  • password: Email account password (use app passwords for Gmail/Outlook)
  • mode: "sync" (mirror server) or "archive" (preserve all messages)

Folder Filter Configuration

  • include: Array of folder patterns to process (empty = all folders)
  • exclude: Array of folder patterns to skip

Message Filter Configuration

  • since: Date string (YYYY-MM-DD) to process messages from
  • subjectKeywords: Array of keywords that must appear in subject line
  • senderKeywords: Array of keywords that must appear in sender addresses
  • recipientKeywords: Array of keywords that must appear in recipient addresses

Production Deployment

Security Considerations

  • Use Environment Variables: Store sensitive credentials in environment variables instead of configuration files
  • Use App Passwords: Use app passwords instead of account passwords for IMAP authentication
  • File Permissions: Store configuration files with restricted permissions (600)
  • Secure Connections: Use HTTPS for CouchDB connections in production
  • SystemD Integration: Use environment variables in systemd service files:
    [Service]
    Environment="MAIL2COUCH_COUCHDB_PASSWORD=secure_password"
    Environment="MAIL2COUCH_IMAP_GMAIL_PASSWORD=app_password"
    ExecStart=/usr/local/bin/mail2couch
    

Monitoring and Maintenance

  • Review sync metadata documents for sync health
  • Monitor CouchDB database sizes and compaction
  • Set up log rotation for application output
  • Schedule regular backups of CouchDB databases

Performance Tuning

  • Use --max-messages/-m to limit processing load
  • Run during off-peak hours for large initial syncs
  • Monitor IMAP server rate limits and connection limits
  • Consider running multiple instances for different accounts

Troubleshooting

Common Issues

Connection Errors:

  • Verify IMAP server settings and credentials
  • Check firewall and network connectivity
  • Ensure correct ports (993 for TLS, 143 for plain)

Authentication Failures:

  • Use app passwords for Gmail, Outlook, and other providers
  • Enable "Less Secure Apps" if required by provider
  • Verify account permissions and 2FA settings

Sync Issues:

  • Check CouchDB connectivity and permissions
  • Review sync metadata documents for error states
  • Verify folder names and patterns match server structure

Performance Problems:

  • Use date filtering (since) for large mailboxes
  • Implement --max-messages/-m limits for initial syncs
  • Monitor server-side rate limiting

For detailed troubleshooting, see the test environment documentation.

Future Plans

CouchDB-Hosted Webmail Viewer

We plan to develop a comprehensive webmail interface for viewing the archived emails directly through CouchDB. This will include:

  • 📧 Modern Web Interface: A responsive, Gmail-style webmail viewer built on CouchDB design documents
  • 🔍 Advanced Search: Full-text search across subjects, senders, and message content
  • 📁 Folder Organization: Browse messages by mailbox with visual indicators and statistics
  • 📎 Attachment Viewer: Direct download and preview of email attachments
  • 📱 Mobile Support: Optimized interface for tablets and smartphones
  • 🎨 Customizable Themes: Multiple UI themes and layout options
  • Real-time Updates: Live synchronization as new emails are archived
  • 🔐 Authentication: Secure access controls and user management
  • 📊 Analytics Dashboard: Email statistics and storage insights

This webmail viewer will be implemented as:

  • CouchDB Design Documents: Views, shows, and list functions for data access
  • Self-contained HTML/CSS/JS: No external dependencies or servers required
  • RESTful Architecture: Clean API endpoints for integration with other tools
  • Progressive Enhancement: Works with JavaScript disabled for basic functionality

The webmail interface will be a separate component that can be optionally installed alongside the core mail2couch storage functionality, maintaining the clean separation between data archival and presentation layers.

Contributing

This project welcomes contributions! Please see CLAUDE.md for development setup and architecture details.

License

This project is licensed under the MIT License. See the LICENSE file for details.