Absenderpruefung erweitern und Postfach auflisten koennen

Die Pruefung suchte woertlich nach "@paypal.de" oder "@paypal.com". Mails
aus einer Versand-Subdomain (e.paypal.de) oder einer Landesvariante
(paypal.at, paypal.co.uk) fielen damit als not_from_paypal durch. Geprueft
wird jetzt die Domain der Absenderadresse an ihrem Ende - "paypal.de.
beispiel.com" ist damit weiterhin kein PayPal, waere bei einer Textsuche
aber durchgerutscht.

check-imap-support.php listet zusaetzlich die letzten 15 Mails mit
Absender, Empfaengerzeilen und Betreff auf und sagt je Mail, ob der
Absender als PayPal gilt. Damit laesst sich ein not_from_paypal in einem
Lauf klaeren statt zu raten. Rein lesend: OP_READONLY, kein \Seen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 22:35:51 +02:00
co-authored by Claude Opus 5
parent d7de0d92cf
commit 43d0fc5578
3 changed files with 86 additions and 1 deletions
+39
View File
@@ -26,6 +26,8 @@ if (PHP_SAPI !== 'cli') {
}
require_once __DIR__ . '/../app/bootstrap.php';
// paypal_from_is_paypal() fuer die Absenderpruefung in der Auflistung.
require_once __DIR__ . '/../app/paypal-inbox.php';
function imap_check_line(string $label, string $value): void
{
@@ -166,6 +168,43 @@ imap_check_line('davon ungelesen', (string) $ungelesen);
fwrite($sock, "a9 LOGOUT\r\n");
fclose($sock);
// Mit der Erweiterung laesst sich zusaetzlich auflisten, was im Postfach
// liegt - die haeufigste Frage bei einer nicht verarbeiteten Mail ist "wer
// war der Absender und an welche Adresse ging sie?". Rein lesend:
// imap_fetch_overview() und imap_fetchheader() setzen kein \Seen.
if (function_exists('imap_open')) {
echo "\n=== Postfachinhalt (nur lesend, letzte 15) ===\n";
$mbox = @imap_open('{' . $host . ':' . $port . $flags . '}' . $mailbox, $user, $pass, OP_READONLY);
if ($mbox === false) {
echo 'Zugriff ueber die imap-Erweiterung fehlgeschlagen: ' . imap_last_error() . "\n";
} else {
$anzahl = imap_num_msg($mbox);
$von = max(1, $anzahl - 14);
for ($msgno = $von; $msgno <= $anzahl; $msgno++) {
$overview = imap_fetch_overview($mbox, (string) $msgno, 0)[0] ?? null;
if ($overview === null) {
continue;
}
$kopf = imap_fetchheader($mbox, $msgno);
$empfaenger = [];
if (preg_match_all('/^(?:Delivered-To|X-Original-To|To|X-Forwarded-To):\s*(.+)$/im', $kopf, $alle)) {
$empfaenger = array_map('trim', $alle[1]);
}
$from = (string) ($overview->from ?? '');
printf(
"#%-3d %s Von: %s\n An: %s\n Betreff: %s\n Absender gilt als PayPal: %s\n",
$msgno,
(int) ($overview->seen ?? 0) === 1 ? 'gelesen ' : 'UNGELESEN',
$from,
implode(' | ', $empfaenger) !== '' ? implode(' | ', $empfaenger) : '(keine Empfaengerzeile gefunden)',
(string) ($overview->subject ?? ''),
paypal_from_is_paypal($from) ? 'ja' : 'NEIN - deshalb not_from_paypal'
);
}
imap_close($mbox);
}
}
echo "\nErgebnis: Postfach erreichbar und Zugangsdaten gueltig.\n";
if (function_exists('imap_open')) {
echo "Die imap-Erweiterung ist vorhanden - scripts/fetch-paypal-payments.php\n"
+21
View File
@@ -234,6 +234,27 @@ try {
$fremd = paypal_process_raw($pdo, $empfaengerA, 'no-reply@beispiel.de', $mailA);
paypal_flow_assert('Mail von fremdem Absender wird abgelehnt', ($fremd['status'] ?? '') === 'not_from_paypal', $failures, $passes);
// Absenderpruefung: PayPal verschickt aus mehreren Domains, eine
// Lookalike-Domain darf aber nie durchgehen.
foreach ([
'"PayPal" <service@paypal.de>' => true,
'service@paypal.com' => true,
'PayPal <service@e.paypal.de>' => true,
'noreply@paypal.at' => true,
'service@paypal.co.uk' => true,
'betrug@paypal.de.beispiel.com' => false,
'paypal@beispiel.de' => false,
'clemens@beispiel.de' => false,
'' => false,
] as $absender => $erwartet) {
paypal_flow_assert(
'Absender "' . ($absender === '' ? '(leer)' : $absender) . '" gilt ' . ($erwartet ? 'als' : 'nicht als') . ' PayPal',
paypal_from_is_paypal($absender) === $erwartet,
$failures,
$passes
);
}
$ohneToken = paypal_process_raw($pdo, 'zahlungen@kaffeeliste.de', 'service@paypal.de', $mailA);
paypal_flow_assert('Adresse ohne Token wird abgelehnt', ($ohneToken['status'] ?? '') === 'no_token', $failures, $passes);