fix(email): derive SMTP auth from credentials
This commit is contained in:
@@ -176,13 +176,11 @@ class GlobalController extends ControllerBase {
|
||||
return $this->error(__('请输入有效的邮箱地址', 'aksrt'));
|
||||
}
|
||||
|
||||
$sent = class_exists('\\AKSRT\\Settings\\Mail')
|
||||
? \AKSRT\Settings\Mail::send_test_email($to)
|
||||
: false;
|
||||
if ($sent) {
|
||||
return $this->success(['message' => '测试邮件已发送']);
|
||||
$result = \AKSRT\Settings\Mail::send_test_email($to);
|
||||
if (is_wp_error($result)) {
|
||||
return $this->error(__('邮件发送失败,详细原因已写入服务器错误日志', 'aksrt'));
|
||||
}
|
||||
return $this->error(__('邮件发送失败,请检查 SMTP 配置', 'aksrt'));
|
||||
return $this->success(['message' => '测试邮件已发送']);
|
||||
}
|
||||
|
||||
public function rest_homepage_tab_posts(\WP_REST_Request $request): \WP_REST_Response {
|
||||
|
||||
+45
-21
@@ -10,24 +10,21 @@ namespace AKSRT\Settings;
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
final class Mail {
|
||||
/** @return list<string> */
|
||||
public static function events(): array {
|
||||
return array_keys(MailTemplates::definitions());
|
||||
}
|
||||
|
||||
/** @return array<string, mixed> */
|
||||
public static function get_smtp(): array {
|
||||
$s = Settings::get_all();
|
||||
$username = trim((string) ($s['mail_smtp_name'] ?? '')) ?: sanitize_email((string) ($s['mail_name'] ?? ''));
|
||||
$password = (string) ($s['mail_passwd'] ?? '');
|
||||
return [
|
||||
'enabled' => !empty($s['mail_smtps']),
|
||||
'host' => trim((string) ($s['mail_host'] ?? '')),
|
||||
'port' => max(1, min(65535, (int) ($s['mail_port'] ?? 465))),
|
||||
'username' => trim((string) ($s['mail_smtp_name'] ?? '')) ?: sanitize_email((string) ($s['mail_name'] ?? '')),
|
||||
'password' => (string) ($s['mail_passwd'] ?? ''),
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'encryption' => in_array(($s['mail_smtpsecure'] ?? 'ssl'), ['ssl', 'tls', ''], true) ? (string) ($s['mail_smtpsecure'] ?? 'ssl') : 'ssl',
|
||||
'from_name' => trim((string) ($s['mail_showname'] ?? '')) ?: get_bloginfo('name'),
|
||||
'from_address' => sanitize_email((string) ($s['mail_name'] ?? '')),
|
||||
'auth' => !empty($s['mail_smtpauth']),
|
||||
'auth' => $username !== '' && $password !== '',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -88,16 +85,25 @@ final class Mail {
|
||||
$definition = MailTemplates::definitions()[$event];
|
||||
$subject = (string) ($cfg['subject'] ?? $default_subject ?: $definition['title']);
|
||||
$content = (string) ($cfg['content'] ?? $default_content ?: $definition['content']);
|
||||
$subject = self::replace_placeholders($subject, $placeholders, false);
|
||||
$content = self::replace_placeholders($content, $placeholders, false);
|
||||
$subject = self::replace_placeholders($subject, $placeholders);
|
||||
$content = self::replace_placeholders($content, $placeholders);
|
||||
$content = self::wrap_html($content, $cfg['global'] ?? []);
|
||||
$headers = ['Content-Type: text/html; charset=UTF-8'];
|
||||
return (bool) wp_mail($to, $subject, $content, $headers);
|
||||
}
|
||||
|
||||
public static function send_test_email(string $to): bool {
|
||||
public static function send_test_email(string $to): bool|\WP_Error {
|
||||
$to = sanitize_email($to);
|
||||
if ($to === '' || !is_email($to)) return false;
|
||||
if ($to === '' || !is_email($to)) {
|
||||
return new \WP_Error('aksrt_invalid_test_email', __('请输入有效的邮箱地址', 'aksrt'));
|
||||
}
|
||||
|
||||
$failure = null;
|
||||
$capture_failure = static function (\WP_Error $error) use (&$failure): void {
|
||||
$failure = $error;
|
||||
};
|
||||
add_action('wp_mail_failed', $capture_failure);
|
||||
|
||||
$site = esc_html((string) get_bloginfo('name'));
|
||||
$subject = '邮件配置测试';
|
||||
$content = "您好,\n\n这是一封来自 {$site} 的邮件配置测试。";
|
||||
@@ -105,7 +111,22 @@ final class Mail {
|
||||
'description' => '此信为系统邮件,请不要直接回复。',
|
||||
'more_content' => '',
|
||||
]);
|
||||
return (bool) wp_mail($to, $subject, $content, ['Content-Type: text/html; charset=UTF-8']);
|
||||
|
||||
try {
|
||||
$sent = (bool) wp_mail($to, $subject, $content, ['Content-Type: text/html; charset=UTF-8']);
|
||||
} finally {
|
||||
remove_action('wp_mail_failed', $capture_failure);
|
||||
}
|
||||
|
||||
if ($sent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$error = $failure instanceof \WP_Error
|
||||
? $failure
|
||||
: new \WP_Error('aksrt_mail_failed', __('wp_mail 返回失败,但未提供详细错误。', 'aksrt'));
|
||||
self::log_test_failure($error);
|
||||
return $error;
|
||||
}
|
||||
|
||||
/** @return array<string, mixed> */
|
||||
@@ -121,20 +142,23 @@ final class Mail {
|
||||
];
|
||||
}
|
||||
|
||||
private static function replace_placeholders(string $value, array $placeholders, bool $html): string {
|
||||
private static function replace_placeholders(string $value, array $placeholders): string {
|
||||
$replace = [];
|
||||
foreach ($placeholders as $key => $replacement) {
|
||||
$replacement = (string) $replacement;
|
||||
if ($html) {
|
||||
$replacement = str_contains($key, 'url') ? esc_url($replacement) : esc_html($replacement);
|
||||
} else {
|
||||
$replacement = wp_strip_all_tags($replacement);
|
||||
}
|
||||
$replace[$key] = $replacement;
|
||||
$replace[$key] = wp_strip_all_tags((string) $replacement);
|
||||
}
|
||||
return strtr($value, $replace);
|
||||
}
|
||||
|
||||
private static function log_test_failure(\WP_Error $error): void {
|
||||
$message = sanitize_text_field($error->get_error_message());
|
||||
$message = preg_replace('/[A-Z0-9._%+\-]+@[A-Z0-9.\-]+\.[A-Z]{2,}/i', '[email]', $message);
|
||||
$message = preg_replace('/\b(?:[a-z0-9-]+\.)+[a-z]{2,}\b/i', '[host]', (string) $message);
|
||||
$message = preg_replace('/\b(?:\d{1,3}\.){3}\d{1,3}\b/', '[ip]', (string) $message);
|
||||
$message = preg_replace('/\b(?:password|passwd|username|user|login|credential)\s*[:=]\s*[^\s,;]+/i', '$1=[redacted]', (string) $message);
|
||||
error_log('[AKSRT] SMTP 测试失败:' . substr((string) $message, 0, 500));
|
||||
}
|
||||
|
||||
private static function wrap_html(string $content, array $global): string {
|
||||
$logo = method_exists(Settings::class, 'logo_url') ? Settings::logo_url() : '';
|
||||
$background = esc_url(AKSRT_URI . '/assets/img/mail-bg.png');
|
||||
|
||||
@@ -62,7 +62,6 @@ final class MailTemplates {
|
||||
'mail_smtp_name' => '',
|
||||
'mail_host' => '',
|
||||
'mail_port' => 465,
|
||||
'mail_smtpauth' => true,
|
||||
'mail_smtpsecure' => 'ssl',
|
||||
'mail_showname' => $site,
|
||||
'mail_title_prefix' => '[' . $site . ']',
|
||||
@@ -89,7 +88,6 @@ final class MailTemplates {
|
||||
['key' => 'mail_smtp_name', 'label' => 'SMTP 用户名', 'type' => 'input', 'default' => $defaults['mail_smtp_name'], 'dependsOn' => ['key' => 'mail_smtps', 'value' => true]],
|
||||
['key' => 'mail_host', 'label' => '邮件服务器地址', 'type' => 'input', 'default' => $defaults['mail_host'], 'dependsOn' => ['key' => 'mail_smtps', 'value' => true]],
|
||||
['key' => 'mail_port', 'label' => 'SMTP 服务器端口', 'type' => 'number', 'default' => $defaults['mail_port'], 'min' => 1, 'max' => 65535, 'dependsOn' => ['key' => 'mail_smtps', 'value' => true]],
|
||||
['key' => 'mail_smtpauth', 'label' => '启用 SMTPAuth', 'type' => 'switch', 'default' => $defaults['mail_smtpauth'], 'dependsOn' => ['key' => 'mail_smtps', 'value' => true]],
|
||||
['key' => 'mail_smtpsecure', 'label' => '加密方式', 'type' => 'select', 'default' => $defaults['mail_smtpsecure'], 'options' => [['label' => 'SSL', 'value' => 'ssl'], ['label' => 'TLS', 'value' => 'tls'], ['label' => '不加密', 'value' => '']], 'dependsOn' => ['key' => 'mail_smtps', 'value' => true]],
|
||||
]],
|
||||
['key' => 'branding', 'title' => '邮件品牌', 'fields' => [
|
||||
|
||||
Reference in New Issue
Block a user