diff --git a/api.php b/api.php index 48252d1..c0c1037 100644 --- a/api.php +++ b/api.php @@ -599,6 +599,7 @@ function sendTicketMail(string $to, string $subject, string $body, string $inRep // Jos mailboxilla on SMTP-asetukset, käytä SMTP:tä $smtpHost = $mailbox['smtp_host'] ?? ''; + error_log("MAIL DEBUG: to={$to} smtpHost={$smtpHost} from={$fromEmail} mailbox_keys=" . implode(',', array_keys($mailbox ?? []))); if ($smtpHost !== '') { return sendViaSMTP($to, $subject, $body, $fromEmail, $fromName, $inReplyTo, $references, $mailbox, $cc); } @@ -618,6 +619,9 @@ function sendTicketMail(string $to, string $subject, string $body, string $inRep return mail($to, $subject, $body, $headers, '-f ' . $fromEmail); } +/** @var string|null Viimeisin SMTP-virhe (palautetaan frontendille) */ +$GLOBALS['smtp_last_error'] = null; + function sendViaSMTP(string $to, string $subject, string $body, string $fromEmail, string $fromName, string $inReplyTo, string $references, array $mailbox, string $cc): bool { $host = $mailbox['smtp_host']; $port = (int)($mailbox['smtp_port'] ?? 587); @@ -628,6 +632,14 @@ function sendViaSMTP(string $to, string $subject, string $body, string $fromEmai $timeout = 15; $errno = 0; $errstr = ''; + $fail = function(string $step, string $detail) use (&$fp) { + $msg = "SMTP $step: $detail"; + error_log($msg); + $GLOBALS['smtp_last_error'] = $msg; + if (isset($fp) && $fp) fclose($fp); + return false; + }; + // Yhteys if ($encryption === 'ssl') { $fp = @stream_socket_client("ssl://{$host}:{$port}", $errno, $errstr, $timeout); @@ -635,13 +647,12 @@ function sendViaSMTP(string $to, string $subject, string $body, string $fromEmai $fp = @stream_socket_client("tcp://{$host}:{$port}", $errno, $errstr, $timeout); } if (!$fp) { - error_log("SMTP connect failed: {$errstr} ({$errno})"); - return false; + return $fail('connect', "{$errstr} ({$errno}) — host={$host}:{$port} enc={$encryption}"); } stream_set_timeout($fp, $timeout); $resp = fgets($fp, 512); - if (substr($resp, 0, 3) !== '220') { fclose($fp); error_log("SMTP banner: $resp"); return false; } + if (substr($resp, 0, 3) !== '220') return $fail('banner', trim($resp)); // EHLO fwrite($fp, "EHLO " . gethostname() . "\r\n"); @@ -655,9 +666,9 @@ function sendViaSMTP(string $to, string $subject, string $body, string $fromEmai if ($encryption === 'tls') { fwrite($fp, "STARTTLS\r\n"); $resp = fgets($fp, 512); - if (substr($resp, 0, 3) !== '220') { fclose($fp); error_log("SMTP STARTTLS: $resp"); return false; } - $crypto = stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT); - if (!$crypto) { fclose($fp); error_log("SMTP TLS negotiation failed"); return false; } + if (substr($resp, 0, 3) !== '220') return $fail('STARTTLS', trim($resp)); + $crypto = @stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT); + if (!$crypto) return $fail('TLS', 'TLS negotiation failed'); // EHLO uudelleen TLS:n jälkeen fwrite($fp, "EHLO " . gethostname() . "\r\n"); while ($line = fgets($fp, 512)) { @@ -669,19 +680,19 @@ function sendViaSMTP(string $to, string $subject, string $body, string $fromEmai if ($user !== '') { fwrite($fp, "AUTH LOGIN\r\n"); $resp = fgets($fp, 512); - if (substr($resp, 0, 3) !== '334') { fclose($fp); error_log("SMTP AUTH: $resp"); return false; } + if (substr($resp, 0, 3) !== '334') return $fail('AUTH', trim($resp)); fwrite($fp, base64_encode($user) . "\r\n"); $resp = fgets($fp, 512); - if (substr($resp, 0, 3) !== '334') { fclose($fp); error_log("SMTP AUTH user: $resp"); return false; } + if (substr($resp, 0, 3) !== '334') return $fail('AUTH user', trim($resp) . " (user={$user})"); fwrite($fp, base64_encode($pass) . "\r\n"); $resp = fgets($fp, 512); - if (substr($resp, 0, 3) !== '235') { fclose($fp); error_log("SMTP AUTH pass: $resp"); return false; } + if (substr($resp, 0, 3) !== '235') return $fail('AUTH pass', trim($resp)); } // MAIL FROM fwrite($fp, "MAIL FROM:<{$fromEmail}>\r\n"); $resp = fgets($fp, 512); - if (substr($resp, 0, 3) !== '250') { fclose($fp); error_log("SMTP MAIL FROM: $resp"); return false; } + if (substr($resp, 0, 3) !== '250') return $fail('MAIL FROM', trim($resp) . " (from={$fromEmail})"); // RCPT TO $allRecipients = array_filter(array_map('trim', explode(',', $to))); @@ -692,14 +703,14 @@ function sendViaSMTP(string $to, string $subject, string $body, string $fromEmai fwrite($fp, "RCPT TO:<{$rcpt}>\r\n"); $resp = fgets($fp, 512); if (substr($resp, 0, 3) !== '250' && substr($resp, 0, 3) !== '251') { - fclose($fp); error_log("SMTP RCPT TO: $resp"); return false; + return $fail('RCPT TO', trim($resp) . " (rcpt={$rcpt})"); } } // DATA fwrite($fp, "DATA\r\n"); $resp = fgets($fp, 512); - if (substr($resp, 0, 3) !== '354') { fclose($fp); error_log("SMTP DATA: $resp"); return false; } + if (substr($resp, 0, 3) !== '354') return $fail('DATA', trim($resp)); // Rakennetaan viesti $messageId = '<' . uniqid('msg_', true) . '@' . (explode('@', $fromEmail)[1] ?? 'localhost') . '>'; @@ -722,7 +733,7 @@ function sendViaSMTP(string $to, string $subject, string $body, string $fromEmai fwrite($fp, $msg); $resp = fgets($fp, 512); - if (substr($resp, 0, 3) !== '250') { fclose($fp); error_log("SMTP send: $resp"); return false; } + if (substr($resp, 0, 3) !== '250') return $fail('send', trim($resp)); // QUIT fwrite($fp, "QUIT\r\n"); @@ -2275,7 +2286,9 @@ switch ($action) { if (!$sent) { http_response_code(500); - echo json_encode(['error' => 'Sähköpostin lähetys epäonnistui']); + $smtpErr = $GLOBALS['smtp_last_error'] ?? ''; + $detail = $smtpErr ? " ({$smtpErr})" : ''; + echo json_encode(['error' => "Sähköpostin lähetys epäonnistui{$detail}"]); break 2; }