From 8baa303760c83a0eb134853d8774c09948cc2ab8 Mon Sep 17 00:00:00 2001 From: Andriy Oblivantsev Date: Sat, 22 Aug 2026 14:36:32 +0100 Subject: [PATCH] test: add internal send->receipt e2e for mail.produktor.io (#104) Submit info@ -> andriy.oblivantsev@ via SMTP AUTH :587 (openssl s_client), poll doveadm until arrival (30s), assert DKIM-Signature present on the delivered copy. Green: submission+receipt+signature all pass. --- scripts/mail-e2e-test.sh | 123 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100755 scripts/mail-e2e-test.sh diff --git a/scripts/mail-e2e-test.sh b/scripts/mail-e2e-test.sh new file mode 100755 index 0000000..110b5e5 --- /dev/null +++ b/scripts/mail-e2e-test.sh @@ -0,0 +1,123 @@ +#!/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 =="