From 3daee2df537a0a50557c9dd946afd68ce93d0005 Mon Sep 17 00:00:00 2001 From: Javier Casares Date: Thu, 12 Feb 2026 13:55:56 +0000 Subject: [PATCH] v2.1.2 --- changelog.txt | 13 ++++++ includes/class-plugin.php | 75 +++++++++++++++++++++++++++++++---- readme.txt | 28 ++++++++++++- robotstxt-smtp-amazonses.php | 4 +- update.json | 10 ++--- vendor/composer/installed.php | 4 +- 6 files changed, 116 insertions(+), 18 deletions(-) diff --git a/changelog.txt b/changelog.txt index a52c6aa..37e6ae3 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,16 @@ += 2.1.2 = + +* Fixed charset encoding issue that caused "expected parameter value, got null" error when sending emails through Amazon SES. +* Added robust charset validation in header parsing to prevent empty or invalid charset values. +* Enhanced charset handling with fallback to UTF-8 when no valid charset is provided. + += 2.1.1 = + +* Added comprehensive Amazon SES debug context to test email error reports. +* Debug information now includes: AWS region, masked access key, SDK version, endpoint URL, and UTC timestamp. +* Enhanced AWS error reporting with request IDs, HTTP status codes, and error codes for easier troubleshooting. +* Improved security by masking access keys in error output (shows only first 4 and last 4 characters). + = 2.1.0 = * Changed uninstall behavior: plugin no longer performs cleanup on uninstall, all data cleanup is now handled by the core SMTP plugin. diff --git a/includes/class-plugin.php b/includes/class-plugin.php index 59d9e76..20d8644 100644 --- a/includes/class-plugin.php +++ b/includes/class-plugin.php @@ -208,9 +208,18 @@ class Plugin { * @return WP_Error|null */ private function deliver_via_amazon_ses( array $mail_context, array $settings, array $parsed_headers, string $access_key, string $secret_key, string $region ): ?WP_Error { + // Prepare debug context for error reporting. + $debug_context = $this->get_ses_debug_context( $access_key, $region ); + $phpmailer = $this->prepare_mailer_for_amazon_ses( $mail_context, $settings, $parsed_headers ); if ( $phpmailer instanceof WP_Error ) { + // Add SES debug context to existing error. + $error_data = $phpmailer->get_error_data(); + if ( is_array( $error_data ) ) { + $error_data['ses_debug'] = $debug_context; + $phpmailer->add_data( $error_data ); + } return $phpmailer; } @@ -231,6 +240,9 @@ class Plugin { 'headers' => $mail_context['headers'], 'attachments' => $mail_context['attachments'], 'phpmailer_exception_code' => $exception->getCode(), + 'phpmailer_exception_file' => $exception->getFile(), + 'phpmailer_exception_line' => $exception->getLine(), + 'ses_debug' => $debug_context, ) ); } @@ -266,12 +278,15 @@ class Plugin { \esc_html( (string) $message ) ), array( - 'to' => $mail_context['to'], - 'subject' => $mail_context['subject'], - 'message' => $mail_context['message'], - 'headers' => $mail_context['headers'], - 'attachments' => $mail_context['attachments'], - 'ses_error_code' => $exception->getAwsErrorCode(), + 'to' => $mail_context['to'], + 'subject' => $mail_context['subject'], + 'message' => $mail_context['message'], + 'headers' => $mail_context['headers'], + 'attachments' => $mail_context['attachments'], + 'ses_error_code' => $exception->getAwsErrorCode(), + 'ses_request_id' => $exception->getAwsRequestId(), + 'ses_http_status_code' => $exception->getStatusCode(), + 'ses_debug' => $debug_context, ) ); } catch ( Throwable $exception ) { @@ -288,6 +303,7 @@ class Plugin { 'message' => $mail_context['message'], 'headers' => $mail_context['headers'], 'attachments' => $mail_context['attachments'], + 'ses_debug' => $debug_context, ) ); } @@ -313,6 +329,12 @@ class Plugin { $content_type = is_string( $parsed_headers['content_type'] ?? '' ) && '' !== $parsed_headers['content_type'] ? $parsed_headers['content_type'] : ( is_string( $default_content_type ) ? $default_content_type : 'text/plain' ); $charset = is_string( $parsed_headers['charset'] ?? '' ) && '' !== $parsed_headers['charset'] ? $parsed_headers['charset'] : ( is_string( $default_charset ) ? $default_charset : 'utf-8' ); + // Ensure charset is never empty, null, or the string "null". + $charset = \trim( (string) $charset ); + if ( '' === $charset || 'null' === \strtolower( $charset ) ) { + $charset = 'utf-8'; + } + // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase $phpmailer->CharSet = $charset; $phpmailer->Encoding = '8bit'; @@ -633,7 +655,11 @@ class Plugin { list( $param, $param_value ) = explode( '=', $part, 2 ); if ( 'charset' === strtolower( trim( $param ) ) ) { - $parsed['charset'] = trim( $param_value, " \n\r\0\x0B\"'" ); + $charset_value = trim( $param_value, " \n\r\0\x0B\"'" ); + // Only set charset if it has a valid non-empty value and is not "null". + if ( '' !== $charset_value && 'null' !== strtolower( $charset_value ) ) { + $parsed['charset'] = $charset_value; + } } } } else { @@ -757,6 +783,41 @@ class Plugin { return $client; } + /** + * Gathers Amazon SES debug context information for error reporting. + * + * @since 2.1.0 + * + * @param string $access_key AWS access key ID. + * @param string $region AWS region identifier. + * + * @return array Debug context with region, masked access key, SDK version, and endpoint. + */ + private function get_ses_debug_context( string $access_key, string $region ): array { + // Mask the access key for security (show first 4 and last 4 characters). + $masked_key = ''; + $key_length = \strlen( $access_key ); + if ( $key_length > 8 ) { + $masked_key = \substr( $access_key, 0, 4 ) . \str_repeat( '*', $key_length - 8 ) . \substr( $access_key, -4 ); + } elseif ( $key_length > 0 ) { + $masked_key = \str_repeat( '*', $key_length ); + } + + // Get AWS SDK version. + $sdk_version = \defined( 'Aws\Sdk::VERSION' ) ? \Aws\Sdk::VERSION : 'unknown'; + + // Build SES endpoint URL. + $endpoint = \sprintf( 'https://email.%s.amazonaws.com', $region ); + + return array( + 'region' => $region, + 'access_key' => $masked_key, + 'sdk_version' => $sdk_version, + 'endpoint' => $endpoint, + 'timestamp' => \gmdate( 'Y-m-d H:i:s' ) . ' UTC', + ); + } + /** * Marks the Amazon SES integration as active. * diff --git a/readme.txt b/readme.txt index 2588444..d31d556 100644 --- a/readme.txt +++ b/readme.txt @@ -3,9 +3,9 @@ Contributors: javiercasares Tags: amazon-ses, smtp, email, mail Requires at least: 6.5 Tested up to: 6.9 -Stable tag: 2.1.0 +Stable tag: 2.1.2 Requires PHP: 8.2 -Version: 2.1.0 +Version: 2.1.2 License: GPL-3.0-or-later License URI: https://www.gnu.org/licenses/gpl-3.0.html @@ -46,5 +46,29 @@ Yes. Network administrators can manage credentials centrally or allow individual == Changelog == += 2.1.2 = +* Fixed charset encoding issue that caused "expected parameter value, got null" error when sending emails through Amazon SES. +* Added robust charset validation in header parsing to prevent empty or invalid charset values. +* Enhanced charset handling with fallback to UTF-8 when no valid charset is provided. + += 2.1.1 = +* Added comprehensive Amazon SES debug context to test email error reports. +* Debug information now includes: AWS region, masked access key, SDK version, endpoint URL, and UTC timestamp. +* Enhanced AWS error reporting with request IDs, HTTP status codes, and error codes for easier troubleshooting. +* Improved security by masking access keys in error output (shows only first 4 and last 4 characters). + += 2.1.0 = +* Changed uninstall behavior: plugin no longer performs cleanup on uninstall, all data cleanup is now handled by the core SMTP plugin. +* This ensures Amazon SES credentials are preserved when only the add-on is removed, and properly cleaned when the core plugin is uninstalled. + += 2.0.1 = +* Version bump for maintenance release. + += 2.0.0 = +* Added Reply-To header support for emails sent via Amazon SES. +* Improved error handling and validation. +* Enhanced compatibility with core SMTP plugin 2.0.0. +* **BREAKING CHANGE**: Minimum PHP version increased to 8.2 (required by AWS SDK for PHP). + = 1.0.0 = * Initial release. diff --git a/robotstxt-smtp-amazonses.php b/robotstxt-smtp-amazonses.php index 1f88516..e92d6cd 100644 --- a/robotstxt-smtp-amazonses.php +++ b/robotstxt-smtp-amazonses.php @@ -3,7 +3,7 @@ * Plugin Name: SMTP (by ROBOTSTXT) Amazon SES * Plugin URI: https://git.robotstxt.es/ROBOTSTXT/robotstxt-smtp-amazonses * Description: Adds Amazon SES configuration support to the ROBOTSTXT SMTP plugin. - * Version: 2.1.0 + * Version: 2.1.2 * Requires at least: 6.5 * Requires PHP: 8.2 * Network: true @@ -26,7 +26,7 @@ if ( ! defined( 'ABSPATH' ) ) { } if ( ! defined( 'ROBOTSTXT_SMTP_AMAZONSES_VERSION' ) ) { - define( 'ROBOTSTXT_SMTP_AMAZONSES_VERSION', '2.1.0' ); + define( 'ROBOTSTXT_SMTP_AMAZONSES_VERSION', '2.1.2' ); } if ( ! defined( 'ROBOTSTXT_SMTP_AMAZONSES_FILE' ) ) { diff --git a/update.json b/update.json index 8a1d28c..cc76819 100644 --- a/update.json +++ b/update.json @@ -1,21 +1,21 @@ { "name": "SMTP (by ROBOTSTXT) Amazon SES", "slug": "robotstxt-smtp-amazonses", - "version": "2.1.0", - "download_url": "https://git.robotstxt.es/ROBOTSTXT/robotstxt-smtp-amazonses/releases/download/2.1.0/robotstxt-smtp-amazonses-2.1.0.zip", + "version": "2.1.2", + "download_url": "https://git.robotstxt.es/ROBOTSTXT/robotstxt-smtp-amazonses/releases/download/2.1.2/robotstxt-smtp-amazonses-2.1.2.zip", "requires": "6.5", "requires_php": "8.2", "tested": "6.9", - "last_updated": "2026-02-09", + "last_updated": "2026-02-12", "author": "ROBOTSTXT", "author_profile": "https://www.robotstxt.es/", "homepage": "https://git.robotstxt.es/ROBOTSTXT/robotstxt-smtp-amazonses", "requires_plugins": ["robotstxt-smtp"], "description": "Adds Amazon SES (Simple Email Service) configuration support to the ROBOTSTXT SMTP plugin. Integrates seamlessly with AWS SDK for PHP to send emails through Amazon SES infrastructure.", - "changelog": "

2.1.0 - 2026-02-09

2.0.0 - 2026-01-29

⚠️ BREAKING CHANGE: This version requires PHP 8.2 or higher due to AWS SDK requirements.

1.0.0 - 2026-01-27

", + "changelog": "

2.1.1 - 2026-02-09

2.1.0 - 2026-02-09

2.0.0 - 2026-01-29

⚠️ BREAKING CHANGE: This version requires PHP 8.2 or higher due to AWS SDK requirements.

1.0.0 - 2026-01-27

", "sections": { "description": "Adds Amazon SES (Simple Email Service) configuration support to the ROBOTSTXT SMTP plugin. Integrates seamlessly with AWS SDK for PHP to send emails through Amazon SES infrastructure.", - "changelog": "

2.1.0 - 2026-02-09

2.0.0 - 2026-01-29

⚠️ BREAKING CHANGE: This version requires PHP 8.2 or higher due to AWS SDK requirements.

1.0.0 - 2026-01-27

" + "changelog": "

2.1.2 - 2026-02-12

2.1.1 - 2026-02-09

2.1.0 - 2026-02-09

2.0.0 - 2026-01-29

⚠️ BREAKING CHANGE: This version requires PHP 8.2 or higher due to AWS SDK requirements.

1.0.0 - 2026-01-27

" }, "banners": { "low": "", diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index f8c496c..6676e8d 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => '__root__', 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => 'e34a30a667b7d9f21f4d1a22d25b81ab38a3b976', + 'reference' => '3a6e6515d6ae39800d7602017ac1596bab7eaa64', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -13,7 +13,7 @@ '__root__' => array( 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => 'e34a30a667b7d9f21f4d1a22d25b81ab38a3b976', + 'reference' => '3a6e6515d6ae39800d7602017ac1596bab7eaa64', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(),