fix: spam-friendly mail headers; docs: monitor.php token todo
Use MTA-style Message-ID and display names on From/To to avoid SpamAssassin MSGID_RANDY and PDS_NAKED_TO_NUMERO. Add todo/12 for HTTP token gate on monitor.php (CLI cron unchanged). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+39
-4
@@ -44,7 +44,7 @@ function sendMail(string $to, string $subject, string $body, ?string $from = nul
|
||||
sendCommand($socket, base64_encode($pass), 235);
|
||||
|
||||
sendCommand($socket, 'MAIL FROM:<' . $envelopeFrom . '>', 250);
|
||||
sendCommand($socket, 'RCPT TO:<' . $to . '>', 250);
|
||||
sendCommand($socket, 'RCPT TO:<' . bareMailAddress($to) . '>', 250);
|
||||
sendCommand($socket, 'DATA', 354);
|
||||
|
||||
$message = buildMessage($fromHeader, $to, $subject, $body);
|
||||
@@ -115,15 +115,50 @@ function readResponse($socket): string
|
||||
return trim($response);
|
||||
}
|
||||
|
||||
function bareMailAddress(string $address): string
|
||||
{
|
||||
$address = trim($address);
|
||||
|
||||
if (preg_match('/<([^>]+)>/', $address, $matches)) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
|
||||
return $address;
|
||||
}
|
||||
|
||||
function encodeDisplayName(string $name): string
|
||||
{
|
||||
if (preg_match('/[\r\n"]/', $name)) {
|
||||
throw new InvalidArgumentException('Invalid display name');
|
||||
}
|
||||
|
||||
if (preg_match('/^[A-Za-z0-9 !\'.\-]+$/', $name)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return '"' . str_replace(['\\', '"'], ['\\\\', '\\"'], $name) . '"';
|
||||
}
|
||||
|
||||
function formatMailAddress(string $email, string $displayName): string
|
||||
{
|
||||
$email = bareMailAddress($email);
|
||||
|
||||
return encodeDisplayName($displayName) . ' <' . $email . '>';
|
||||
}
|
||||
|
||||
function buildMessage(string $from, string $to, string $subject, string $body): string
|
||||
{
|
||||
$domain = env('DOMAIN', '0012.de');
|
||||
$date = gmdate('D, d M Y H:i:s') . ' +0000';
|
||||
$messageId = sprintf('<%s@%s>', bin2hex(random_bytes(8)), $domain);
|
||||
// MTA-style ID (time + pid) — avoids SpamAssassin MSGID_RANDY on random hex IDs.
|
||||
$messageId = sprintf('<%s.%s@%s>', gmdate('YmdHis'), getmypid(), $domain);
|
||||
|
||||
$fromHeader = formatMailAddress($from, env('SMTP_FROM_NAME', '0012 Monitoring'));
|
||||
$toHeader = formatMailAddress($to, env('MAIL_TO_NAME', 'Alert Recipient'));
|
||||
|
||||
$headers = [
|
||||
"From: {$from}",
|
||||
"To: {$to}",
|
||||
"From: {$fromHeader}",
|
||||
"To: {$toHeader}",
|
||||
"Subject: {$subject}",
|
||||
"Date: {$date}",
|
||||
"Message-ID: {$messageId}",
|
||||
|
||||
Reference in New Issue
Block a user