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.
This commit is contained in:
Executable
+123
@@ -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: <e2e-$(date +%s)@${MAIL_HOSTNAME}>
|
||||||
|
|
||||||
|
${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 =="
|
||||||
Reference in New Issue
Block a user