# Test Infrastructure: SMTP Server (Mailpit) ## Overview The test SMTP server uses [Mailpit](https://mailpit.axllent.org/), a lightweight email testing tool that captures all outgoing emails without delivering them. It provides both an SMTP server for sending and a web UI for inspecting captured messages. ## Image & Ports - **Image**: `axllent/mailpit:latest` - **SMTP port**: 1025 - **Web UI / API**: `http://localhost:8025` ## Configuration | Setting | Value | Description | |---------|-------|-------------| | `MP_SMTP_AUTH_ACCEPT_ANY` | `1` | Accept any SMTP credentials (or none) — no real authentication | | `MP_SMTP_AUTH_ALLOW_INSECURE` | `1` | Allow auth over plain SMTP (no TLS required) — dev only | | `MP_MAX_MESSAGES` | `500` | Maximum stored messages before oldest are auto-deleted | Mailpit accepts all emails regardless of sender/recipient domain. No emails leave the server — they are captured and viewable in the web UI. ## SMTP Connection Settings For `appsettings.Development.json` (Notification Service): ```json { "Smtp": { "Server": "localhost", "Port": 1025, "AuthMode": "None", "FromAddress": "scada-notifications@company.com", "ConnectionTimeout": 30 } } ``` Since `MP_SMTP_AUTH_ACCEPT_ANY` is enabled, the Notification Service can use any auth mode: - **No auth**: Connect directly, no credentials needed. - **Basic Auth**: Any username/password will be accepted (useful for testing the auth code path without a real server). - **OAuth2**: Not supported by Mailpit. For OAuth2 testing, use a real Microsoft 365 tenant. ## Mailpit API Mailpit exposes a REST API at `http://localhost:8025/api` for programmatic access: | Endpoint | Method | Description | |----------|--------|-------------| | `/api/v1/info` | GET | Server info (version, message count) | | `/api/v1/messages` | GET | List messages (supports `?limit=N`) | | `/api/v1/message/{id}` | GET | Read a specific message | | `/api/v1/messages` | DELETE | Delete all messages | | `/api/v1/search?query=...` | GET | Search messages | ## Verification 1. Check the container is running: ```bash docker ps --filter name=scadalink-smtp ``` 2. Open the web UI at `http://localhost:8025` to view captured emails. 3. Send a test email using `curl` or any SMTP client: ```bash # Using Python's smtplib (one-liner) python3 -c " import smtplib; from email.mime.text import MIMEText msg = MIMEText('Test body'); msg['Subject'] = 'Test'; msg['From'] = 'test@example.com'; msg['To'] = 'user@example.com' smtplib.SMTP('localhost', 1025).sendmail('test@example.com', ['user@example.com'], msg.as_string()) print('Sent') " ``` ## CLI Tool The `infra/tools/smtp_tool.py` script provides a convenient CLI for interacting with the SMTP server and Mailpit API. This tool uses only Python standard library modules — no additional dependencies required. **Commands**: ```bash # Check SMTP connectivity and Mailpit status python infra/tools/smtp_tool.py check # Send a test email python infra/tools/smtp_tool.py send --to user@example.com --subject "Alarm: Tank High Level" --body "Tank level exceeded 95%" # Send with BCC (matches ScadaLink notification delivery pattern) python infra/tools/smtp_tool.py send --to scada-notifications@company.com --bcc "operator1@company.com,operator2@company.com" --subject "Shift Report" # List captured messages python infra/tools/smtp_tool.py list # Read a specific message by ID python infra/tools/smtp_tool.py read --id # Clear all messages python infra/tools/smtp_tool.py clear ``` Use `--host` and `--port` to override SMTP defaults (localhost:1025), `--api` for the Mailpit API URL. Run with `--help` for full usage. ## Relevance to ScadaLink Components - **Notification Service** — test SMTP delivery, BCC recipient handling, plain-text formatting, and store-and-forward retry behavior (Mailpit can be stopped/started to simulate transient failures). - **Store-and-Forward Engine** — verify buffered retry by stopping the SMTP container and observing queued notifications. ## Notes - Mailpit does **not** support OAuth2 Client Credentials authentication. To test the OAuth2 code path, use a real Microsoft 365 tenant (see Q12 in `docs/plans/questions.md`). - To simulate SMTP failures for store-and-forward testing, stop the container: `docker compose stop smtp`. Restart with `docker compose start smtp`. - The web UI at `http://localhost:8025` provides real-time message inspection, search, and message source viewing. - No data persistence — messages are stored in a temporary database inside the container and lost on container removal.