Changelog¶
All notable changes to the Mail API project are documented here.
[3.1.1] - 2026-02-16¶
Security Hardening & Brute-Force Mitigation¶
fail2ban Overhaul¶
- Fixed: Postfix jail was detecting attacks but never banning — conflicting
iptables-multiport(jail.local) vsnftables-multiport(jail.d) actions caused silent failures - Fixed: Removed broken
banned_dbsecondary action from all jails - New: Created
postfix-sasljail with custom filter (/etc/fail2ban/filter.d/postfix-sasl.conf) that catches both SMTPS SASL failures and submissionauth=0disconnect patterns - Hardened: All mail jails now use
maxretry=3,findtime=600,bantime=86400(24h) - Whitelisted: Admin client IP (154.160.3.228) in all jails via
ignoreip - Standardized all jails on
nftables-multiportaction
Postfix Rate Limiting¶
- Added
smtpd_client_auth_rate_limit = 3(max 3 auth attempts/min per IP) - Added
smtpd_client_recipient_rate_limit = 50 - Reduced
smtpd_error_sleep_timeto 5s,smtpd_soft_error_limitto 3,smtpd_hard_error_limitto 5 - Added
smtpd_junk_command_limit = 3
Dovecot Hardening¶
- Increased
auth_failure_delayfrom 2s to 5s (slows brute-force) - Fixed master user file permissions (
chmod 644 /etc/dovecot/dovecot-master-users)
Documentation¶
- Added
DOCS_SECURITY_HARDENING.md— Complete security configuration reference
[3.1.0] - 2026-02-15¶
Delegated Permissions + Mailbox Purge¶
Delegated Permissions System¶
Domain-scoped permission delegation allowing admins to grant non-admin users the ability to manage users or domains within specific domains.
Available permissions: - manage_users — Create, update, enable/disable, reset password, delete, purge users within granted domain(s) - manage_domains — View, update, enable/disable domains and DNS records within granted domain(s)
Security features: - Admin accounts are hidden from delegated user listings - Delegated users cannot modify, delete, or disable admin accounts - Domain creation/deletion and DKIM regeneration remain admin-only - Cloudflare DNS configuration remains admin-only
New API endpoints (4): - POST /api/v1/permissions — Grant a permission (admin-only) - DELETE /api/v1/permissions/{id} — Revoke a permission (admin-only) - GET /api/v1/permissions — List all permissions, filter by email/domain (admin-only) - GET /api/v1/permissions/mine — Get current user's own permissions
New database table: - user_permissions — Stores email, permission, domain, granted_by, granted_at
Updated endpoints (all user + domain endpoints): - User endpoints now use require_permission("manage_users") instead of require_admin_token - Domain list, DNS records, verify, update, enable/disable now use require_permission("manage_domains") - All mutation endpoints check domain scope for non-admin callers
Frontend: - New Permissions management page (admin-only) at /permissions - Sidebar entry with ShieldCheck icon - Grant dialog with domain/permission dropdowns - Revoke with confirmation dialog
New files: - mailapi/models/permissions.py — UserPermission SQLAlchemy model - mailapi/api/v1/permissions.py — Permission CRUD endpoints - frontend/src/pages/permissions/PermissionsPage.tsx - frontend/src/lib/api/endpoints/permissions.ts - tests/test_api/test_permissions.py — 21 tests
Updated files: - mailapi/dependencies.py — Added require_permission() factory, AuthenticatedToken.permitted_domains() - mailapi/api/v1/users.py — Domain scoping, admin protection, admin hiding - mailapi/api/v1/domains.py — Domain scoping for delegated access - .env — ADMIN_EMAILS now includes 4 admin addresses
Mailbox Purge Endpoint¶
New endpoint: POST /api/v1/users/{email}/purge - Permanently deletes ALL emails in every folder without removing the account - Uses doveadm expunge and doveadm quota recalc under the hood - Requires manage_users permission for the user's domain - Frontend purge button added to User Detail page with destructive confirmation dialog
Admin Email Updates¶
ADMIN_EMAILS now includes: - ewilson@solutechhub.com - ewilson@resourcegsr.com - ewilson@samueltengey.com - postmaster@resourcegsr.com
Tests¶
21 new permission tests covering: - Grant/revoke/list/mine endpoints - Duplicate, invalid permission, nonexistent user/domain validation - Cannot grant permissions to admin accounts - Delegated user can create users in permitted domain - Delegated user blocked from other domains (403) - User list filters by permitted domain - Admin accounts hidden from delegated user list - Cannot modify/delete admin accounts - Domain list filtered for delegated users - Domain create/delete remain admin-only
Total: 113 backend tests (all passing)
[3.0.0] - 2026-02-15¶
Admin Dashboard + Email/Password Authentication¶
Major release adding a full React admin dashboard and replacing token-only authentication with email/password login.
Admin Dashboard (Frontend)¶
Stack: React 18 + TypeScript + Vite + Tailwind CSS + shadcn/ui
URL: https://portal.solutechhub.com
Features: - Email/password login (no API token needed) - Dashboard with delivery stats widgets - Domain management: list, create, DNS records (with copy), DKIM, Cloudflare, verification - User management: list, create, detail, edit, enable/disable, password reset, quota bars - Mail compose (rich text TipTap editor, attachments, CC/BCC), sent mail list, message status - Mailbox reader (3-panel: folders, message list, message viewer, search, attachment download) - Security dashboard, quarantine (bulk actions), trusted senders, analysis history, audit log, settings - Token management: list, create (one-time display with copy) - Delivery stats with charts (recharts), domain stats - Dark/light mode toggle - Responsive design
Deployment: - Static build served by Nginx at portal.solutechhub.com - API proxied at /api/v1/ to backend on port 7792 - SSL via Let's Encrypt (auto-renew)
New files: - /etc/nginx/sites-available/portal.solutechhub.com.conf - /opt/mailapi/frontend/ — full React application
Email/Password Authentication¶
Replaced token-only authentication with email/password login. Users authenticate with their mailbox credentials (same password used for IMAP/SMTP).
New endpoint: POST /api/v1/auth/login - Verifies credentials against vmail mailbox table (SSHA512 hashing) - Returns a session token with sliding inactivity timeout + hard expiry - Admin detection via ADMIN_EMAILS environment variable - Rate limiting: 5 failed attempts per email → 15-minute lockout
New endpoint: POST /api/v1/auth/logout - Deactivates the session token server-side
Session security:
| Setting | Value | Configurable |
|---|---|---|
| Inactivity timeout | 10 minutes | SESSION_INACTIVITY_MINUTES |
| Hard expiry | 8 hours | SESSION_HARD_EXPIRY_HOURS |
| Rate limit | 5 attempts / 15 min | In-memory, per email |
New files: - mailapi/api/v1/auth.py — Login/logout endpoints with rate limiting - mailapi/models/vmail.py — Added verify_password() static method
Updated files: - mailapi/dependencies.py — Added sliding window inactivity check + hard expiry enforcement - mailapi/api/v1/router.py — Registered auth router - settings.py — Added admin_emails, session_inactivity_minutes, session_hard_expiry_hours
New environment variables:
ADMIN_EMAILS=ewilson@solutechhub.com,ewilson@resourcegsr.com
SESSION_INACTIVITY_MINUTES=10
SESSION_HARD_EXPIRY_HOURS=8
Backend Unit Tests¶
92 tests across 10 test files using pytest + httpx async client: - test_auth.py — 17 tests (login, logout, rate limiting, password verification) - test_tokens.py — 17 tests - test_domains.py — 13 tests - test_users.py — 8 tests - test_mail.py — 4 tests - test_security.py — 11 tests - test_stats.py — 5 tests - test_dns_verifier.py — 5 tests - test_dkim_manager.py — 7 tests - test_smtp_client.py — 5 tests
Test infrastructure uses SQLite in-memory databases with all external services mocked.
E2E Tests¶
28 Playwright tests covering all critical user flows: - Authentication (login, error handling, session persistence) - Navigation (sidebar, routing) - Domains, Users, Mail, Security, Tokens, Stats pages
DNS Changes¶
portal.solutechhub.comA record → 161.97.157.206mail.solutechhub.comA record → 161.97.157.206
[2.2.1] - 2026-02-13¶
Claude AI Scanner Disabled, Rspamd Neural Network + Optimizations¶
AI Scanner Disabled¶
The Claude AI Sieve filter has been disabled. Rspamd's built-in spam detection (Bayes, rules, greylisting, phishing module, ClamAV) provides sufficient coverage for the current scale. The AI scanner added ~$0.001-0.003 API cost per email and 8 seconds latency for marginal benefit.
What changed: - /var/vmail/sieve/dovecot.sieve - Removed filter "ai-scanner" and AI header checks; removed vnd.dovecot.filter require - /opt/mailapi/.env - Set AI_SECURITY_ENABLED=false - Dovecot reloaded to pick up new Sieve script
What was preserved (not deleted): - AI security API endpoints still exist (16 endpoints at /api/v1/security/*) - Database tables intact (ai_security_analysis, quarantine, trusted_senders, etc.) - Filter script still at /usr/lib/dovecot/sieve-filter/ai-scanner - Can be re-enabled by reversing the Sieve changes and setting AI_SECURITY_ENABLED=true
Rspamd Neural Network Module Enabled¶
Added machine learning-based spam detection using Rspamd's built-in neural network module. Uses Redis as backend, learns from Rspamd's own scoring over time.
New config files: - /etc/rspamd/local.d/neural.conf - Two-model configuration (SHORT + LONG) - /etc/rspamd/local.d/neural_group.conf - Symbol weights for neural scores
Two-model design:
| Model | Training Samples | Retrain Cycle | Expiry | Spam Weight | Ham Weight |
|---|---|---|---|---|---|
| SHORT | 100 | Every 10 uses | 1 day | +2.0 | -1.0 |
| LONG | 5000 | Every 25 uses | 7 days | +3.0 | -3.0 |
- SHORT model: Adapts quickly to new spam patterns (retrains daily)
- LONG model: Stable, high-confidence model (retrains weekly, needs more data)
- Both auto-learn from Rspamd scores: spam >= 8, ham <= -2
- No manual training required — learns passively from mail flow
Rollback (disable neural):
Re-enable AI scanner (if needed):
# 1. Restore Sieve script with AI filter
cat > /var/vmail/sieve/dovecot.sieve << 'EOF'
require ["fileinto", "vnd.dovecot.filter"];
if header :is "X-Spam-Flag" "YES" {
fileinto "Junk";
stop;
}
filter "ai-scanner";
if header :is "X-AI-Threat-Category" "critical" {
fileinto "Junk";
stop;
}
if header :is "X-AI-Threat-Category" "high" {
fileinto "Junk";
stop;
}
EOF
# 2. Compile and reload
sievec /var/vmail/sieve/dovecot.sieve
systemctl reload dovecot
# 3. Enable in .env
sed -i 's/AI_SECURITY_ENABLED=false/AI_SECURITY_ENABLED=true/' /opt/mailapi/.env
systemctl restart mailapi
Dovecot Auth Cache Enabled¶
Added authentication caching to reduce MariaDB queries from Mailspring polling.
File: /etc/dovecot/dovecot.conf
| Setting | Value | Purpose |
|---|---|---|
auth_cache_size | 10M | Cache auth lookups in memory |
auth_cache_ttl | 1 hour | Positive cache lifetime |
auth_cache_negative_ttl | 5 mins | Failed auth cache lifetime |
Note: iRedMail doesn't use /etc/dovecot/conf.d/, all config is in dovecot.conf directly.
Rspamd Rate Limiting Configured¶
Created /etc/rspamd/local.d/ratelimit.conf with per-recipient and bounce rate limits:
| Bucket | Burst | Rate | Purpose |
|---|---|---|---|
to | 100 | 1/s (~3600/hr) | Per recipient |
to_ip | 50 | 0.5/s (~1800/hr) | Per recipient+IP |
to_ip_from | 30 | 0.3/s (~1080/hr) | Per sender+IP |
bounce_to | 5 | 0.02/s (~72/hr) | Bounce per recipient |
bounce_to_ip | 3 | 0.01/s (~36/hr) | Bounce per IP+recipient |
Rspamd OpenPhish + Reputation Module Enabled¶
Phishing (/etc/rspamd/local.d/phishing.conf): - OpenPhish enabled (was disabled) — adds second phishing URL database alongside PhishTank
Reputation (/etc/rspamd/local.d/reputation.conf): - IP reputation tracking via Redis - SPF reputation tracking via Redis - DKIM domain reputation tracking via Redis - Builds sender reputation over time, improves scoring accuracy
Netdata Disabled¶
Stopped and disabled Netdata monitoring service to free ~434MB RAM. Can be re-enabled:
[2.2.0] - 2026-02-12¶
Rspamd Migration & Server Performance Overhaul¶
Major infrastructure change: Replaced Amavis + SpamAssassin + OpenDKIM with Rspamd as a single, modern milter. This reduces memory usage by ~500MB, eliminates the Amavis content_filter bottleneck, and consolidates DKIM signing, spam filtering, greylisting, and ARC into one service.
What Changed (v2.1.0 → v2.2.0)¶
Services Disabled¶
| Service | Was | Now | Reason |
|---|---|---|---|
| Amavis | active | disabled | Replaced by Rspamd milter |
| SpamAssassin | active (via Amavis) | disabled | Replaced by Rspamd spam scoring |
| OpenDKIM | active | disabled | Replaced by Rspamd DKIM signing |
Services Added/Changed¶
| Service | Port | Purpose |
|---|---|---|
| Rspamd milter | 11332 | Postfix milter (replaces Amavis content_filter) |
| Rspamd normal worker | 11333 | Scan worker |
| Rspamd controller | 11334 | Web UI and management API |
| Redis | 6379 | Rspamd backend (Bayes, greylisting, rate limiting) |
Rspamd Configuration¶
New config files created in /etc/rspamd/local.d/:
| File | Purpose |
|---|---|
dkim_signing.conf | DKIM signing for all 3 domains (resourcegsr.com, samueltengey.com, solutechhub.com) |
arc.conf | ARC (Authenticated Received Chain) signing |
worker-proxy.inc | Milter mode for Postfix integration |
worker-controller.inc | Web UI with password authentication |
redis.conf | Redis backend on 127.0.0.1:6379, db 1 |
antivirus.conf | ClamAV integration via unix socket |
classifier-bayes.conf | Bayesian classifier using Redis backend with autolearn |
actions.conf | Score thresholds: greylist=4, add_header=6, reject=15 |
greylist.conf | Greylisting: expire=1d, timeout=5min |
milter_headers.conf | X-Spamd-Bar, X-Spam-Level, Authentication-Results headers |
DKIM keys copied from /etc/opendkim/keys/ to /etc/rspamd/dkim/: - /etc/rspamd/dkim/resourcegsr.com.mail.key - /etc/rspamd/dkim/samueltengey.com.mail.key - /etc/rspamd/dkim/solutechhub.com.mail.key
Postfix Changes¶
| Setting | Before (v2.1.0) | After (v2.2.0) |
|---|---|---|
content_filter | smtp-amavis:[127.0.0.1]:10024 | (removed) |
smtpd_milters | (not set) | inet:127.0.0.1:11332 |
non_smtpd_milters | (not set) | inet:127.0.0.1:11332 |
milter_protocol | (not set) | 6 |
milter_default_action | (not set) | accept |
milter_mail_macros | (not set) | i {mail_addr} {client_addr} {client_name} {auth_authen} |
inet_protocols | all | ipv4 (server has no IPv6) |
default_destination_concurrency_limit | 20 | 50 |
smtp_destination_concurrency_limit | 20 | 50 |
smtpd_client_connection_count_limit | (default) | 5 |
smtpd_client_connection_rate_limit | (default) | 10 |
minimal_backoff_time | 300s | 30s |
maximal_backoff_time | 4000s | 300s |
maximal_queue_lifetime | 5d | 3d |
bounce_queue_lifetime | 5d | 1d |
queue_run_delay | 300s | 60s |
smtp_connection_cache_time_limit | (default) | 10s |
The smtp-amavis transport in master.cf was commented out (not removed, for rollback).
MariaDB Performance Tuning¶
File: /etc/mysql/mariadb.conf.d/50-server.cnf
| Setting | Before | After |
|---|---|---|
max_connections | (default 151) | 100 |
thread_cache_size | (default 0) | 16 |
table_open_cache | (default 2000) | 400 |
table_definition_cache | (default 400) | 400 |
tmp_table_size | (default 16M) | 64M |
max_heap_table_size | (default 16M) | 64M |
wait_timeout | (default 28800) | 300 |
interactive_timeout | (default 28800) | 300 |
innodb_buffer_pool_size | (default 128M) | 512M |
innodb_log_file_size | (default 48M) | 128M |
innodb_flush_method | (default fsync) | O_DIRECT |
innodb_io_capacity | (default 200) | 2000 |
innodb_io_capacity_max | (default 2000) | 4000 |
query_cache_type | (default OFF) | 1 (ON) |
query_cache_size | (default 1M) | 64M |
query_cache_limit | (default 1M) | 2M |
slow_query_log | (off) | 1 (ON) |
long_query_time | (default 10) | 1 |
DKIM Manager Updated¶
dkim_manager.py was updated to write Rspamd DKIM signing config in addition to legacy OpenDKIM tables when domains are created/deleted. New methods: - _update_rspamd_dkim() - Copies DKIM key to /etc/rspamd/dkim/, adds domain block to dkim_signing.conf and arc.conf, reloads Rspamd - remove_dkim_config() - Now also removes domain from Rspamd configs
Backups¶
Pre-migration configs backed up to /opt/mailapi/backups/pre-optimization-20260212/:
backups/pre-optimization-20260212/
├── postfix/ # main.cf, master.cf, mysql/*.cf
├── dovecot/ # dovecot.conf, conf.d/*
├── amavis/ # conf.d/50-user, all amavis config
├── spamassassin/ # local.cf, all SA config
├── opendkim/ # opendkim.conf, KeyTable, SigningTable, TrustedHosts, keys/
└── mariadb/ # my.cnf, 50-server.cnf, conf.d/*
Rollback Procedures¶
Full Rollback: v2.2.0 → v2.1.0 (Restore Amavis + SpamAssassin + OpenDKIM)¶
If Rspamd is causing issues and you need to revert to the previous Amavis-based stack:
# 1. Stop Rspamd
systemctl stop rspamd
systemctl disable rspamd
# 2. Restore Postfix config (removes milter, restores content_filter)
cp /opt/mailapi/backups/pre-optimization-20260212/postfix/main.cf /etc/postfix/main.cf
cp /opt/mailapi/backups/pre-optimization-20260212/postfix/master.cf /etc/postfix/master.cf
# 3. Restore MariaDB config
cp /opt/mailapi/backups/pre-optimization-20260212/mariadb/50-server.cnf /etc/mysql/mariadb.conf.d/50-server.cnf
# 4. Restore OpenDKIM config
cp /opt/mailapi/backups/pre-optimization-20260212/opendkim/opendkim.conf /etc/opendkim.conf
cp /opt/mailapi/backups/pre-optimization-20260212/opendkim/KeyTable /etc/opendkim/KeyTable
cp /opt/mailapi/backups/pre-optimization-20260212/opendkim/SigningTable /etc/opendkim/SigningTable
cp /opt/mailapi/backups/pre-optimization-20260212/opendkim/TrustedHosts /etc/opendkim/TrustedHosts
# 5. Restore Amavis config
cp /opt/mailapi/backups/pre-optimization-20260212/amavis/amavis/conf.d/50-user /etc/amavis/conf.d/50-user
# 6. Re-enable and start old services
systemctl enable amavis opendkim spamassassin
systemctl start opendkim
systemctl start amavis
systemctl start spamassassin
# 7. Restart Postfix and MariaDB with restored configs
systemctl restart mariadb
systemctl stop postfix && systemctl start postfix # Full restart needed for inet_protocols
# 8. Verify mail flow
echo "Test" | mail -s "Rollback test" ewilson@resourcegsr.com
tail -f /var/log/mail.log
Verification after rollback:
# All old services should be active
systemctl is-active amavis opendkim spamassassin postfix dovecot
# Rspamd should be inactive
systemctl is-active rspamd
# Check mail flow uses Amavis (should see smtp-amavis in logs)
tail -20 /var/log/mail.log | grep amavis
# Check DKIM signing via OpenDKIM
tail -20 /var/log/mail.log | grep opendkim
Partial Rollback: Rspamd Only (Keep MariaDB + Postfix Tuning)¶
If you only want to revert Rspamd but keep the performance tuning:
# 1. Stop Rspamd
systemctl stop rspamd
systemctl disable rspamd
# 2. Remove milter config from Postfix, restore content_filter
postconf -e "smtpd_milters ="
postconf -e "non_smtpd_milters ="
postconf -e "content_filter = smtp-amavis:[127.0.0.1]:10024"
# 3. Uncomment smtp-amavis transport in master.cf
# Edit /etc/postfix/master.cf and uncomment the smtp-amavis section
# 4. Re-enable old services
systemctl enable amavis opendkim
systemctl start opendkim amavis
# 5. Reload Postfix
systemctl reload postfix
Rollback: MariaDB Tuning Only¶
# Restore original MariaDB config
cp /opt/mailapi/backups/pre-optimization-20260212/mariadb/50-server.cnf /etc/mysql/mariadb.conf.d/50-server.cnf
systemctl restart mariadb
Rollback: Postfix inet_protocols Only¶
# Restore IPv4+IPv6 (only if server has IPv6 connectivity)
postconf -e "inet_protocols = all"
systemctl stop postfix && systemctl start postfix
AI-Powered Email Security¶
AI Threat Detection Engine¶
Complete AI-powered email analysis using Anthropic Claude:
New Service: - ai_analyzer.py - Core AI analysis engine with pre-analysis scanning, caching, and quarantine
New API Endpoints - AI Security (16 endpoints): - POST /api/v1/security/analyze - Analyze email for threats - GET /api/v1/security/stats - Security statistics dashboard - GET /api/v1/security/history - Analysis history (paginated) - GET /api/v1/security/quarantine - List quarantined emails - GET /api/v1/security/quarantine/{id} - Quarantine item detail - POST /api/v1/security/quarantine/{id}/release - Release from quarantine - DELETE /api/v1/security/quarantine/{id} - Delete quarantined email - POST /api/v1/security/quarantine/{id}/report-safe - Report false positive - POST /api/v1/security/quarantine/bulk-delete - Bulk delete - POST /api/v1/security/quarantine/bulk-release - Bulk release - GET /api/v1/security/trusted-senders - List trusted senders - POST /api/v1/security/trusted-senders - Add trusted sender - DELETE /api/v1/security/trusted-senders/{id} - Remove trusted sender - GET /api/v1/security/settings - Get security settings - PUT /api/v1/security/settings - Update security settings - GET /api/v1/security/events - Security audit log
Features: - Pre-analysis engine (free, no API cost): URL typosquatting detection, suspicious TLD checking, URL shortener detection, dangerous attachment scanning, double extension detection - Claude AI content analysis for phishing, BEC, social engineering, and spam - SHA256-based analysis caching to avoid duplicate API calls - Configurable threat score thresholds (flag/block/quarantine) - Trusted senders whitelist (exact, domain, wildcard patterns) - Full quarantine management with release/delete/report-safe - Security audit event log for compliance - Graceful fallback when AI is unavailable (default: deliver)
Dovecot Sieve Integration¶
Automatic inline filtering for all incoming email:
New Files: - /usr/lib/dovecot/sieve-filter/ai-scanner - Dovecot filter script (calls local API) - /var/vmail/sieve/dovecot.sieve - Global sieve rules
Features: - SpamAssassin runs first (free, fast) → catches ~95% of spam - AI Scanner runs second (API cost) → catches sophisticated threats - Adds X-AI-Threat-Score, X-AI-Threat-Category, X-AI-Action headers - Critical/high threats automatically filed to Junk folder - Works transparently with all email clients (Mailspring, Thunderbird, Outlook) - 8-second timeout with graceful fallback - Dovecot sieve_extprograms plugin (configured in dovecot.conf directly for iRedMail)
Database Schema¶
New Tables (6): - ai_security_analysis - Analysis results and threat scores - quarantine - Quarantined email storage - trusted_senders - Sender whitelist patterns - security_settings - AI configuration (singleton) - security_events - Audit log - ai_analysis_cache - Content hash cache (auto-expires)
SQL schema file: /opt/mailapi/database/ai_security_schema.sql
New Dependencies¶
anthropic>=0.40.0- Anthropic Claude API SDK
Configuration¶
New Environment Variables:
Documentation¶
- Created
DOCS_AI_SECURITY.md- Comprehensive AI security documentation - Updated
README.md- Added all new sections and 51 endpoint reference
[2.0.0] - 2026-02-10¶
Major Features Added¶
Domain Automation System¶
Complete automation for email domain provisioning:
New Services: - dkim_manager.py - Automated DKIM key generation and OpenDKIM configuration - dns_verifier.py - DNS record verification (SPF, DKIM, DMARC, MX) - cloudflare_client.py - Cloudflare DNS API integration for automatic DNS setup
New API Endpoints - Domains: - POST /api/v1/domains - Create domain with auto DKIM generation - GET /api/v1/domains - List all domains with statistics - PATCH /api/v1/domains/{domain} - Update domain settings - DELETE /api/v1/domains/{domain} - Delete domain - POST /api/v1/domains/{domain}/enable - Enable domain - POST /api/v1/domains/{domain}/disable - Disable domain - GET /api/v1/domains/{domain}/dns-records - Get required DNS records - GET /api/v1/domains/{domain}/verify - Verify DNS configuration - POST /api/v1/domains/{domain}/regenerate-dkim - Rotate DKIM keys - POST /api/v1/domains/{domain}/configure-cloudflare - Auto-configure via Cloudflare - GET /api/v1/domains/{domain}/users - List users in domain - GET /api/v1/domains/cloudflare/zones - List Cloudflare zones
Features: - Automatic DKIM key generation (2048-bit RSA) - OpenDKIM KeyTable and SigningTable auto-update - DNS record generation (SPF, DKIM, DMARC, MX) - DNS verification with detailed status reporting - Optional Cloudflare integration for zero-touch DNS setup - Domain enable/disable for billing/suspension workflows
User Management System¶
Complete user lifecycle management:
New API Endpoints - Users: - POST /api/v1/users - Create mailbox user - GET /api/v1/users - List all users (with filters) - GET /api/v1/users/{email} - Get user details - PATCH /api/v1/users/{email} - Update user - DELETE /api/v1/users/{email} - Delete user - POST /api/v1/users/{email}/enable - Enable user - POST /api/v1/users/{email}/disable - Disable user - POST /api/v1/users/{email}/reset-password - Reset password
Features: - SSHA512 password hashing (iRedMail compatible) - Quota management and tracking - Used quota display from Dovecot - Last login tracking (IMAP/POP3/LDA) - Automatic maildir path generation - Self-forwarding entry creation - User enable/disable for account suspension
Enhanced Models¶
Updated vmail.py models: - Full Mailbox model with all iRedMail fields - Full Domain model with quota and settings - Added Forwardings model - Added UsedQuota model (Dovecot integration) - Added LastLogin model - Password hashing utility method - Maildir path generation utility
New Schemas: - domain.py - Domain management schemas (12 new models) - user.py - User management schemas (9 new models)
Configuration Updates¶
New Environment Variables:
# Mail Server Settings
MAIL_SERVER_HOSTNAME=mail.resourcegsr.com
MAIL_SERVER_IP=161.97.157.206
# DKIM Settings
DKIM_SELECTOR=mail
DKIM_KEY_BITS=2048
OPENDKIM_KEYS_DIR=/etc/opendkim/keys
OPENDKIM_KEYTABLE=/etc/opendkim/KeyTable
OPENDKIM_SIGNINGTABLE=/etc/opendkim/SigningTable
# Cloudflare API
CLOUDFLARE_API_TOKEN=
CLOUDFLARE_ENABLED=false
Dependencies Added¶
dnspython>=2.4.0- DNS lookups and verificationhttpx>=0.25.0- Async HTTP client for Cloudflare API
Documentation¶
- Created
ROADMAP.md- Strategic product roadmap - Created
CHANGELOG.md- Version history tracking
[1.0.0] - 2024-09¶
Initial Release¶
Core Features: - FastAPI-based REST API for iRedMail - Mail sending via SMTP submission (port 587) - Mailbox access via IMAP (read-only) - Delivery statistics and tracking - Token-based authentication (admin + user tokens)
API Endpoints: - /api/v1/mail/send - Send email - /api/v1/mail/{message_id}/status - Check delivery status - /api/v1/mail/sent - List sent messages - /api/v1/mailbox/{email}/folders - List folders - /api/v1/mailbox/{email}/messages - List messages - /api/v1/mailbox/{email}/messages/{uid} - Get message - /api/v1/mailbox/{email}/messages/{uid}/attachment/{index} - Get attachment - /api/v1/mailbox/{email}/search - Search messages - /api/v1/stats/delivery - Delivery statistics - /api/v1/stats/domain/{domain} - Domain statistics - /api/v1/stats/message/{message_id} - Message statistics - /api/v1/tokens/create - Create API token - /api/v1/tokens/list - List tokens - /api/v1/tokens/me - Get current token info - /api/v1/tokens/{token_id} - Delete token - /api/v1/tokens/{token_id}/activate - Activate token - /api/v1/tokens/{token_id}/deactivate - Deactivate token
Database Tables: - api_tokens - API authentication tokens - api_messages - Sent message tracking - api_message_recipients - Per-recipient delivery tracking
Infrastructure: - Systemd service (mailapi.service) - Nginx reverse proxy with SSL - Uvicorn ASGI server with 4 workers - Multi-database support (vmail, amavisd, iredapd)
Upgrade Notes¶
Upgrading from 1.0.0 to 2.0.0¶
-
Install new dependencies:
-
Update environment variables:
-
Restart service:
-
Verify new endpoints:
Breaking Changes¶
None. Version 2.0.0 is fully backward compatible with 1.0.0.
Roadmap¶
See the project roadmap for future features and strategic direction.
Next Up (Phase 3)¶
- Email template engine (Jinja2)
- Webhook notifications for delivery events
- Scheduled/delayed sending
- Email tracking (open/click)
- Multi-tenant billing integration