Skip to content

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) vs nftables-multiport (jail.d) actions caused silent failures
  • Fixed: Removed broken banned_db secondary action from all jails
  • New: Created postfix-sasl jail with custom filter (/etc/fail2ban/filter.d/postfix-sasl.conf) that catches both SMTPS SASL failures and submission auth=0 disconnect 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-multiport action

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_time to 5s, smtpd_soft_error_limit to 3, smtpd_hard_error_limit to 5
  • Added smtpd_junk_command_limit = 3

Dovecot Hardening

  • Increased auth_failure_delay from 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.com A record → 161.97.157.206
  • mail.solutechhub.com A 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):

rm /etc/rspamd/local.d/neural.conf /etc/rspamd/local.d/neural_group.conf
systemctl reload rspamd

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:

systemctl enable netdata && systemctl start netdata


[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:

ANTHROPIC_API_KEY=sk-ant-api03-...
AI_SECURITY_ENABLED=true
AI_MODEL=claude-sonnet-4-5-20250929

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 verification
  • httpx>=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

  1. Install new dependencies:

    cd /opt/mailapi
    ./venv/bin/pip install dnspython httpx
    

  2. Update environment variables:

    # Edit /opt/mailapi/.env and add new variables
    nano /opt/mailapi/.env
    

  3. Restart service:

    systemctl restart mailapi
    

  4. Verify new endpoints:

    curl https://mail-api.solutechhub.com/docs
    

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