feat: implement real IMAP message parsing with native CouchDB attachments

- Replace placeholder message generation with actual IMAP message fetching using go-message library
- Add per-account CouchDB databases for better organization and isolation
- Implement native CouchDB attachment storage with proper revision management
- Add command line argument parsing with --max-messages flag for controlling message processing limits
- Support both sync and archive modes with proper document synchronization
- Add comprehensive test environment with Podman containers (GreenMail IMAP server + CouchDB)
- Implement full MIME multipart parsing for proper body and attachment extraction
- Add TLS and plain IMAP connection support based on port configuration
- Update configuration system to support sync vs archive modes
- Create test scripts and sample data for development and testing

Key technical improvements:
- Real email envelope and header processing with go-imap v2 API
- MIME Content-Type and Content-Disposition parsing for attachment detection
- CouchDB document ID generation using mailbox_uid format for uniqueness
- Duplicate detection and prevention to avoid re-storing existing messages
- Proper error handling and connection management for IMAP operations

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2025-08-01 17:04:10 +02:00
commit ea6235b674
22 changed files with 1262 additions and 66 deletions

79
test/dovecot/dovecot.conf Normal file
View file

@ -0,0 +1,79 @@
# Dovecot configuration for testing mail2couch
# Basic settings
protocols = imap
listen = *
# SSL/TLS settings - make optional for easier testing
ssl = optional
ssl_cert = </etc/dovecot/ssl/server.crt
ssl_key = </etc/dovecot/ssl/server.key
# Authentication
auth_mechanisms = plain login
disable_plaintext_auth = no
# User database
passdb {
driver = passwd-file
args = scheme=plain username_format=%u /etc/dovecot/passwd
}
userdb {
driver = passwd-file
args = username_format=%u /etc/dovecot/users
}
# Mail location
mail_location = maildir:/var/mail/%u
# Mailbox settings
namespace inbox {
type = private
separator = /
prefix =
location =
inbox = yes
hidden = no
list = yes
subscriptions = yes
mailbox Drafts {
special_use = \Drafts
}
mailbox Junk {
special_use = \Junk
}
mailbox Trash {
special_use = \Trash
}
mailbox Sent {
special_use = \Sent
}
}
# Services
service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
}
service auth {
unix_listener auth-userdb {
mode = 0666
}
}
# Logging
log_path = /dev/stdout
info_log_path = /dev/stdout
debug_log_path = /dev/stdout
# Process limits
default_process_limit = 10
default_client_limit = 100

51
test/dovecot/entrypoint.sh Executable file
View file

@ -0,0 +1,51 @@
#!/bin/sh
# Entrypoint script for Dovecot test container
set -e
echo "Installing Dovecot..."
apk add --no-cache dovecot dovecot-lmtpd openssl
echo "Setting up directories..."
mkdir -p /var/mail
mkdir -p /var/run/dovecot
mkdir -p /var/log/dovecot
# Create dovecot user if it doesn't exist
if ! getent passwd dovecot > /dev/null 2>&1; then
addgroup -g 97 dovecot
adduser -D -u 97 -G dovecot -s /sbin/nologin dovecot
fi
# Set proper ownership
chown -R dovecot:dovecot /var/mail
chown -R dovecot:dovecot /var/run/dovecot
chown -R root:dovecot /etc/dovecot
chmod -R 0640 /etc/dovecot
chmod 0644 /etc/dovecot/dovecot.conf
# Generate SSL certificates if they don't exist
if [ ! -f /etc/dovecot/ssl/server.crt ] || [ ! -f /etc/dovecot/ssl/server.key ]; then
echo "Generating SSL certificates..."
mkdir -p /etc/dovecot/ssl
# Generate DH parameters (small for testing)
openssl dhparam -out /etc/dovecot/ssl/dh.pem 1024
# Generate private key
openssl genrsa -out /etc/dovecot/ssl/server.key 2048
# Generate certificate
openssl req -new -key /etc/dovecot/ssl/server.key -out /etc/dovecot/ssl/server.csr -subj "/C=US/ST=Test/L=Test/O=Mail2Couch/CN=localhost"
openssl x509 -req -days 365 -in /etc/dovecot/ssl/server.csr -signkey /etc/dovecot/ssl/server.key -out /etc/dovecot/ssl/server.crt
rm /etc/dovecot/ssl/server.csr
fi
# Ensure SSL directory permissions
chown -R dovecot:dovecot /etc/dovecot/ssl
chmod 600 /etc/dovecot/ssl/server.key
chmod 644 /etc/dovecot/ssl/server.crt
echo "Starting Dovecot..."
exec dovecot -F

8
test/dovecot/passwd Normal file
View file

@ -0,0 +1,8 @@
# Password database for Dovecot testing
# Format: username:password
# Test accounts with simple passwords for testing
testuser1:password123
testuser2:password456
syncuser:syncpass
archiveuser:archivepass

8
test/dovecot/ssl/dh.pem Normal file
View file

@ -0,0 +1,8 @@
-----BEGIN DH PARAMETERS-----
MIIBDAKCAQEAjcUSAHFs60qgDRg/cT7byhuhF3vwZQhmm1QToCFgG4VWu/EOVXq2
kHxjxmo3hBuJCqUZqTAyF91Tum7A2QuQhXFrxOpRF8EiyVSgBabjN/WcEHIow1uh
Vtb4JOcDl/Q9IJfFT6zyXdQQiHPBOWnpOBKXeQQQIx5plgsrmK0cTO2ZxtyrmHHp
wxtE3INKYuBlGH3Y0zghc+Hoezpf/hbIHZibGQ0l79EtBDQjqmqoDJCIiv5gsTt8
9VpkR6FFvjWTNOb5qY10W/PRhLGjioX29bp1B6qW5PNJcd//cqrBLebKlkAoXnyx
x0uTUy6pmmIt5vdYxx0symrMXZEjrL7uzwIBAgICAOE=
-----END DH PARAMETERS-----

View file

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDVzCCAj+gAwIBAgIUYvkZSKbVH08s/3B70AW8IEpTB/kwDQYJKoZIhvcNAQEL
BQAwVDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDTALBgNVBAcMBFRlc3Qx
EzARBgNVBAoMCk1haWwyQ291Y2gxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0yNTA4
MDExNDIyMzVaFw0yNjA4MDExNDIyMzVaMFQxCzAJBgNVBAYTAlVTMQ0wCwYDVQQI
DARUZXN0MQ0wCwYDVQQHDARUZXN0MRMwEQYDVQQKDApNYWlsMkNvdWNoMRIwEAYD
VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs
leQcVLlKx7/bJGPo1k2Ccu1nKlMv8zdnvYpQ4c3vBVS1vPK3wxVnFz5JWiNPy/vx
Td1mVCm9Lsd9bc3QwntbWFW8EO7DNBbCiUbfPeDsURpRT0evuPfCgWHr8pJ0/ZDW
knco7/MEatakliVkpf3O6WdbNkx7I+MO2KOePCzIVi5Pxwb3ldXO4OxHsgfKG331
HEFdIqqccpimnIUYSYNmyRrowBixanMW/wq7rcInJYuYRnw9wEg24jOfpKLJHuwo
eN8zBzGFJe9xzqeaLNa9RBJCJSYp6AnDV6mDpeIEgwrW/66NWYqwVEcC3IJ22Et5
LGN5xSzXvFIzgP20y5s5AgMBAAGjITAfMB0GA1UdDgQWBBTkgYZGp2s74D+1ltyl
rudF/o7jODANBgkqhkiG9w0BAQsFAAOCAQEATc6ekhuk32meLuxhalz6lNwBxfDg
EG3gGUxNwehwgiNCcKIKQFtCwjJde6drOobkRDANtb7g3gSlAxlUCPsO6xnL1c6E
HhehFn++7HOpXvmEy/mnoqBL6PLzRZRMRlDynlPVV9Y82zsdrQiQEhGyNTfgP5dk
u9RMIMQl1hIK381V738b5MXfdpYhmRiTGEd6hCxCnzkx0OakCLM9lnJASr0dYPuh
LYKoClxhr3sV/JsgAmx91BuHGpzaPYQ2zFvCJSqD2ihM7zIl9K2bLIUR87/CznyH
JuPRbgt6/cxzwdqflP73j+TTZdlI4gckEA3H0WhNN4nB2SEjTgS+kDctMA==
-----END CERTIFICATE-----

View file

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCsleQcVLlKx7/b
JGPo1k2Ccu1nKlMv8zdnvYpQ4c3vBVS1vPK3wxVnFz5JWiNPy/vxTd1mVCm9Lsd9
bc3QwntbWFW8EO7DNBbCiUbfPeDsURpRT0evuPfCgWHr8pJ0/ZDWknco7/MEatak
liVkpf3O6WdbNkx7I+MO2KOePCzIVi5Pxwb3ldXO4OxHsgfKG331HEFdIqqccpim
nIUYSYNmyRrowBixanMW/wq7rcInJYuYRnw9wEg24jOfpKLJHuwoeN8zBzGFJe9x
zqeaLNa9RBJCJSYp6AnDV6mDpeIEgwrW/66NWYqwVEcC3IJ22Et5LGN5xSzXvFIz
gP20y5s5AgMBAAECggEAOfBaM76ns/iqKpYlamnjfIs7svotEjhrHcsub6fWvEsE
XLzRmSqHeWP+t55oo2XeL2zOCofvuUDGnQ+rXE2mHwzhP3FJzsOibm2qmtCJvZwe
ozRj4xTMLILGDnGRhHAJ21cxZM9lPNLnOzri0868DeYimib49xAdroLBLyKRgDGN
O7OAwA4KWAebZRBU8cowEF87WGAI2hOLJA5WIKX7X9SiRDx5sNnDpTpqJvyvuleR
D/wKGHzkQiZx8WNJx5A571dilfKEp8S49o4sJdz8DQ/4ruVov2Vi+nSdMEzHnp5m
M7ZlZ7IcJRJDKPrDYasmxvtM8EiKyJf87/DPANfYFwKBgQDa+ANr2pGg2oMJVJIq
r/mj8wtRsLRYFgfs96BUwp7e9Vo+Rx+E0uZxGGMul6hn4b2/TQljLfiX/CP8ZTyw
MStlNlnAXaF425JNuQIFQ2wGGiGdsx2I1WNw7co4UPVVjH11nr3o30g+NDJcp7Tq
rvpKvGbeoZtHzOj0bF7fA/B7qwKBgQDJxcUUEH5A50n3oUP99aK/DzSA7kcte2Aw
tjv9hbPnbOmcM24Fm+KU7bsRYt9QPa0PU2lV3O1KrHj4q+QRcPFl2P2mzZC+Hzmx
H8dEjMmH8YdrjGqethMoUHJCguNfskNwjgWFlxTSBLY+NffghXNzZgiF9d6WqF48
iqwH+HsAqwKBgQCb/B2D0Xn4WnEKToKpgh6WGmcv1G9EaL1Qo75FYzcFoUaeItBj
MFIUssjEwiinh/pBssFDM9Zpfqar//pRkVVWjnc1P/3tOI1qbKbx1Ou5FRhpXNVn
SovCQMLTh2idfq1JAsJKh/TQyyItOxL4M5n9b2Tgp8MUTPaOWDzlJctEbQKBgEVu
oNq+sjNzY6iq/dKubEqC2PZlCGlGQ1t/2jTrhXTlrZ3qtLmJYvcMt4rMEzxxfNQB
SAYb+CvyHc60l87Ipsj9WovDwUMrS5b/8HpOWCtHmeoQb8Adt4nv5OGuWL/dgAeD
V7MYwjljFbNiruG8CnZzbgtrCCWf2o3KylgT0X/xAoGAUhSdBge5Vpg0JcT1VDgm
q5rgc6dD1LJtXfBaq3w4kHYK/iLFcPOLUKcIJXNbhMwWza/JwVYK6hsCIw3/b4va
NhJ8ABpC3fZqkl28glEF8bnrPAkE1akn2GiBaaEbTCQRMrhZ2SW3JCyjX6yCvvvz
m7b2ZpDMJEMIBmgrK70E3Oo=
-----END PRIVATE KEY-----

8
test/dovecot/users Normal file
View file

@ -0,0 +1,8 @@
# User database for Dovecot testing
# Format: username:uid:gid:home:shell
# Test user accounts
testuser1::1001:1001:/var/mail/testuser1::
testuser2::1002:1002:/var/mail/testuser2::
syncuser::1003:1003:/var/mail/syncuser::
archiveuser::1004:1004:/var/mail/archiveuser::