You've already forked wc-tier-and-package-prices
Version 1.3.1 - Switch to SecureLicenseClient with signature verification
- Upgraded from LicenseClient to SecureLicenseClient with HMAC-SHA256 response signature verification - Added Server Secret configuration field for secure communication - Added rate limit exception handling with retry time display - Added signature verification error handling - Added URL validation error handling (SSRF protection) - Updated all translation files with new strings - Compiled .mo files for all 7 language variants Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -154,6 +154,16 @@ if (!class_exists('WC_TPP_Settings')) {
|
||||
'desc_tip' => true,
|
||||
),
|
||||
|
||||
array(
|
||||
'title' => __('Server Secret', 'wc-tier-package-prices'),
|
||||
'desc' => __('The shared secret for secure communication with the license server.', 'wc-tier-package-prices'),
|
||||
'id' => 'wc_tpp_license_server_secret',
|
||||
'type' => 'password',
|
||||
'default' => '',
|
||||
'css' => 'min-width:400px;',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
|
||||
array(
|
||||
'title' => __('License Status', 'wc-tier-package-prices'),
|
||||
'type' => 'wc_tpp_license_status',
|
||||
@@ -188,13 +198,14 @@ if (!class_exists('WC_TPP_Settings')) {
|
||||
|
||||
$license_key = sanitize_text_field(wp_unslash($_POST['license_key'] ?? ''));
|
||||
$server_url = esc_url_raw(wp_unslash($_POST['server_url'] ?? ''));
|
||||
$server_secret = sanitize_text_field(wp_unslash($_POST['server_secret'] ?? ''));
|
||||
|
||||
if (empty($license_key) || empty($server_url)) {
|
||||
wp_send_json_error(array('message' => __('License key and server URL are required.', 'wc-tier-package-prices')));
|
||||
if (empty($license_key) || empty($server_url) || empty($server_secret)) {
|
||||
wp_send_json_error(array('message' => __('License key, server URL, and server secret are required.', 'wc-tier-package-prices')));
|
||||
}
|
||||
|
||||
try {
|
||||
$client = $this->get_license_client($server_url);
|
||||
$client = $this->get_license_client($server_url, $server_secret);
|
||||
$domain = $this->get_current_domain();
|
||||
$result = $client->validate($license_key, $domain);
|
||||
|
||||
@@ -212,16 +223,37 @@ if (!class_exists('WC_TPP_Settings')) {
|
||||
'status' => $this->get_cached_license_status(),
|
||||
));
|
||||
|
||||
} catch (\Magdev\WcLicensedProductClient\Exception\RateLimitExceededException $e) {
|
||||
wp_send_json_error(array(
|
||||
'message' => sprintf(
|
||||
/* translators: %d: Number of seconds to wait */
|
||||
__('Rate limit exceeded. Please try again in %d seconds.', 'wc-tier-package-prices'),
|
||||
$e->retryAfter ?? 60
|
||||
),
|
||||
'code' => 'rate_limit_exceeded',
|
||||
'retry_after' => $e->retryAfter,
|
||||
));
|
||||
} catch (\Magdev\WcLicensedProductClient\Security\SignatureException $e) {
|
||||
delete_transient('wc_tpp_license_status');
|
||||
wp_send_json_error(array(
|
||||
'message' => __('Response signature verification failed. Please check your server secret.', 'wc-tier-package-prices'),
|
||||
'code' => 'signature_error',
|
||||
));
|
||||
} catch (\Magdev\WcLicensedProductClient\Exception\LicenseException $e) {
|
||||
delete_transient('wc_tpp_license_status');
|
||||
wp_send_json_error(array(
|
||||
'message' => $e->getMessage(),
|
||||
'code' => $e->errorCode ?? 'unknown',
|
||||
));
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
wp_send_json_error(array(
|
||||
'message' => $e->getMessage(),
|
||||
'code' => 'invalid_url',
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
delete_transient('wc_tpp_license_status');
|
||||
wp_send_json_error(array(
|
||||
'message' => $e->getMessage(),
|
||||
'message' => __('An unexpected error occurred. Please try again.', 'wc-tier-package-prices'),
|
||||
'code' => 'exception',
|
||||
));
|
||||
}
|
||||
@@ -239,13 +271,14 @@ if (!class_exists('WC_TPP_Settings')) {
|
||||
|
||||
$license_key = sanitize_text_field(wp_unslash($_POST['license_key'] ?? ''));
|
||||
$server_url = esc_url_raw(wp_unslash($_POST['server_url'] ?? ''));
|
||||
$server_secret = sanitize_text_field(wp_unslash($_POST['server_secret'] ?? ''));
|
||||
|
||||
if (empty($license_key) || empty($server_url)) {
|
||||
wp_send_json_error(array('message' => __('License key and server URL are required.', 'wc-tier-package-prices')));
|
||||
if (empty($license_key) || empty($server_url) || empty($server_secret)) {
|
||||
wp_send_json_error(array('message' => __('License key, server URL, and server secret are required.', 'wc-tier-package-prices')));
|
||||
}
|
||||
|
||||
try {
|
||||
$client = $this->get_license_client($server_url);
|
||||
$client = $this->get_license_client($server_url, $server_secret);
|
||||
$domain = $this->get_current_domain();
|
||||
$result = $client->activate($license_key, $domain);
|
||||
|
||||
@@ -269,14 +302,34 @@ if (!class_exists('WC_TPP_Settings')) {
|
||||
|
||||
wp_send_json_error(array('message' => $result->message));
|
||||
|
||||
} catch (\Magdev\WcLicensedProductClient\Exception\RateLimitExceededException $e) {
|
||||
wp_send_json_error(array(
|
||||
'message' => sprintf(
|
||||
/* translators: %d: Number of seconds to wait */
|
||||
__('Rate limit exceeded. Please try again in %d seconds.', 'wc-tier-package-prices'),
|
||||
$e->retryAfter ?? 60
|
||||
),
|
||||
'code' => 'rate_limit_exceeded',
|
||||
'retry_after' => $e->retryAfter,
|
||||
));
|
||||
} catch (\Magdev\WcLicensedProductClient\Security\SignatureException $e) {
|
||||
wp_send_json_error(array(
|
||||
'message' => __('Response signature verification failed. Please check your server secret.', 'wc-tier-package-prices'),
|
||||
'code' => 'signature_error',
|
||||
));
|
||||
} catch (\Magdev\WcLicensedProductClient\Exception\LicenseException $e) {
|
||||
wp_send_json_error(array(
|
||||
'message' => $e->getMessage(),
|
||||
'code' => $e->errorCode ?? 'unknown',
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
wp_send_json_error(array(
|
||||
'message' => $e->getMessage(),
|
||||
'code' => 'invalid_url',
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
wp_send_json_error(array(
|
||||
'message' => __('An unexpected error occurred. Please try again.', 'wc-tier-package-prices'),
|
||||
'code' => 'exception',
|
||||
));
|
||||
}
|
||||
@@ -285,14 +338,18 @@ if (!class_exists('WC_TPP_Settings')) {
|
||||
/**
|
||||
* Get license client instance
|
||||
*
|
||||
* @param string $server_url License server URL.
|
||||
* Uses SecureLicenseClient for HMAC signature verification.
|
||||
*
|
||||
* @param string $server_url License server URL.
|
||||
* @param string $server_secret Shared secret for signature verification.
|
||||
* @return \Magdev\WcLicensedProductClient\LicenseClientInterface
|
||||
*/
|
||||
private function get_license_client(string $server_url): \Magdev\WcLicensedProductClient\LicenseClientInterface {
|
||||
private function get_license_client(string $server_url, string $server_secret): \Magdev\WcLicensedProductClient\LicenseClientInterface {
|
||||
$httpClient = \Symfony\Component\HttpClient\HttpClient::create();
|
||||
return new \Magdev\WcLicensedProductClient\LicenseClient(
|
||||
return new \Magdev\WcLicensedProductClient\SecureLicenseClient(
|
||||
httpClient: $httpClient,
|
||||
baseUrl: $server_url,
|
||||
serverSecret: $server_secret,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -402,6 +459,7 @@ if (!class_exists('WC_TPP_Settings')) {
|
||||
return {
|
||||
license_key: $('#wc_tpp_license_key').val(),
|
||||
server_url: $('#wc_tpp_license_server_url').val(),
|
||||
server_secret: $('#wc_tpp_license_server_secret').val(),
|
||||
nonce: '<?php echo esc_js($nonce); ?>'
|
||||
};
|
||||
}
|
||||
@@ -420,8 +478,8 @@ if (!class_exists('WC_TPP_Settings')) {
|
||||
|
||||
$validateBtn.on('click', function() {
|
||||
var data = getLicenseData();
|
||||
if (!data.license_key || !data.server_url) {
|
||||
alert('<?php echo esc_js(__('Please enter both license server URL and license key.', 'wc-tier-package-prices')); ?>');
|
||||
if (!data.license_key || !data.server_url || !data.server_secret) {
|
||||
alert('<?php echo esc_js(__('Please enter license server URL, license key, and server secret.', 'wc-tier-package-prices')); ?>');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -443,8 +501,8 @@ if (!class_exists('WC_TPP_Settings')) {
|
||||
|
||||
$activateBtn.on('click', function() {
|
||||
var data = getLicenseData();
|
||||
if (!data.license_key || !data.server_url) {
|
||||
alert('<?php echo esc_js(__('Please enter both license server URL and license key.', 'wc-tier-package-prices')); ?>');
|
||||
if (!data.license_key || !data.server_url || !data.server_secret) {
|
||||
alert('<?php echo esc_js(__('Please enter license server URL, license key, and server secret.', 'wc-tier-package-prices')); ?>');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user