#!/usr/bin/env bash # # mail-e2e-test.sh — internal send -> receipt proof for mail.produktor.io # # Mandate (#104): # (a) submit a message info@ -> andriy.oblivantsev@ via port 587 (auth, # credentials from .env, NEVER echoed), poll doveadm search until the # message arrives (timeout ~30s), assert receipt AND that a # DKIM-Signature header is present. # (b) exit non-zero on failure with a clear reason. # # Usage: scripts/mail-e2e-test.sh # set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" ENV_FILE="${REPO_DIR}/.env" CONTAINER=mailserver TIMEOUT_S=${TIMEOUT_S:-30} POLL_INTERVAL_S=${POLL_INTERVAL_S:-2} if [[ ! -f "${ENV_FILE}" ]]; then echo "FAIL: missing ${ENV_FILE}" >&2 exit 1 fi # shellcheck disable=SC1090 source "${ENV_FILE}" FROM_USER="info" TO_USER="andriy.oblivantsev" FROM="${FROM_USER}@${MAIL_DOMAIN}" TO="${TO_USER}@${MAIL_DOMAIN}" PASSWORD="${INFO_PASSWORD}" [[ -n "${MAIL_DOMAIN}" ]] || { echo "FAIL: MAIL_DOMAIN empty in .env" >&2; exit 1; } [[ -n "${INFO_PASSWORD}" ]] || { echo "FAIL: INFO_PASSWORD empty in .env" >&2; exit 1; } echo "== mail e2e: ${FROM} -> ${TO} (port 587) ==" # Clean inbox for a deterministic poll. docker exec "${CONTAINER}" doveadm expunge -u "${TO}" mailbox INBOX all 2>/dev/null || true SUBJECT="e2e-test $(date +%s)" BODY="e2e internal receipt proof for #104 $(date -u -Is)" MSG="From: ${FROM} To: ${TO} Subject: ${SUBJECT} Date: $(date -R) Message-ID: ${BODY} " # (a) submit via SMTP AUTH on 587 (TLS required). Password never echoed. # Use openssl s_client so we can send a valid EHLO (curl hardcodes the host # name, which postfix rejects as an invalid HELO). AUTH PLAIN is base64 of # "\0user\0pass"; built in a subshell, never printed. AUTH_B64="$(printf '\0%s\0%s' "${FROM}" "${PASSWORD}" | base64 -w0)" set +e { printf 'EHLO mail.%s\r\n' "${MAIL_DOMAIN}" printf 'AUTH PLAIN %s\r\n' "${AUTH_B64}" printf 'MAIL FROM:<%s>\r\n' "${FROM}" printf 'RCPT TO:<%s>\r\n' "${TO}" printf 'DATA\r\n' printf '%s' "${MSG}" printf '\r\n.\r\n' printf 'QUIT\r\n' } | timeout 60 openssl s_client -quiet -starttls smtp -connect 127.0.0.1:587 2>/dev/null > /tmp/e2e-smtp.out SMTP_RC=${PIPESTATUS[1]} set -e if [[ ${SMTP_RC} -ne 0 ]]; then echo "FAIL: submission via 587 failed (openssl rc=${SMTP_RC})" >&2 grep -iE '^(250|550|554|501|535|535|454)' /tmp/e2e-smtp.out >&2 || true exit 1 fi # Require: accepted RCPT (250) and accepted DATA / queued (250 2.0.0). if ! grep -qE '^250 2.1.0 Ok' /tmp/e2e-smtp.out; then echo "FAIL: recipient not accepted" >&2 sed 's/^/ smtp: /' /tmp/e2e-smtp.out >&2 exit 1 fi if ! grep -qE '^250 2.0.0 Ok' /tmp/e2e-smtp.out; then echo "FAIL: message not queued" >&2 sed 's/^/ smtp: /' /tmp/e2e-smtp.out >&2 exit 1 fi echo "OK: submitted via 587" # (b) poll doveadm search until message arrives (timeout). received="" elapsed=0 while [[ ${elapsed} -lt ${TIMEOUT_S} ]]; do received="$(docker exec "${CONTAINER}" doveadm search -u "${TO}" mailbox INBOX 2>/dev/null | awk '{print $1}' | tr -d ' ' | tr '\n' ' ')" if [[ -n "${received}" ]]; then break fi sleep "${POLL_INTERVAL_S}" elapsed=$((elapsed + POLL_INTERVAL_S)) done if [[ -z "${received}" ]]; then echo "FAIL: no message arrived in INBOX within ${TIMEOUT_S}s" >&2 exit 1 fi echo "OK: received in INBOX (ids: ${received})" # Assert DKIM-Signature header is present on the delivered copy. # (INBOX was expunged first, so the only message present is the one just sent.) if ! docker exec "${CONTAINER}" doveadm fetch -u "${TO}" 'hdr.DKIM-Signature' all 2>/dev/null | grep -qiE 'hdr.dkim-signature: v=1;'; then echo "FAIL: delivered message carries NO DKIM-Signature header" >&2 exit 1 fi echo "OK: DKIM-Signature header present on delivered copy" echo "== PASS =="