Changeset 3395179
- Timestamp:
- 11/13/2025 04:14:53 PM (4 months ago)
- Location:
- pulse-chat-ai
- Files:
-
- 23 added
- 4 edited
-
tags/2.2.3 (added)
-
tags/2.2.3/LICENSE.txt (added)
-
tags/2.2.3/assets (added)
-
tags/2.2.3/assets/chat-feedback-solid-standard.svg (added)
-
tags/2.2.3/assets/script.js (added)
-
tags/2.2.3/assets/style.css (added)
-
tags/2.2.3/dist (added)
-
tags/2.2.3/dist/admin (added)
-
tags/2.2.3/dist/admin/admin.js (added)
-
tags/2.2.3/dist/assets (added)
-
tags/2.2.3/dist/assets/globals.css (added)
-
tags/2.2.3/dist/chunks (added)
-
tags/2.2.3/dist/chunks/globals-B-Fr2V0D.js (added)
-
tags/2.2.3/dist/frontend (added)
-
tags/2.2.3/dist/frontend/frontend.js (added)
-
tags/2.2.3/includes (added)
-
tags/2.2.3/includes/class-asset-loader.php (added)
-
tags/2.2.3/includes/class-license-manager.php (added)
-
tags/2.2.3/languages (added)
-
tags/2.2.3/languages/index.php (added)
-
tags/2.2.3/pulse-chat-ai.php (added)
-
tags/2.2.3/readme.txt (added)
-
tags/2.2.3/uninstall.php (added)
-
trunk/includes/class-asset-loader.php (modified) (1 diff)
-
trunk/includes/class-license-manager.php (modified) (7 diffs)
-
trunk/pulse-chat-ai.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
pulse-chat-ai/trunk/includes/class-asset-loader.php
r3392240 r3395179 97 97 if (isset($entry_data['imports']) && is_array($entry_data['imports'])) { 98 98 foreach ($entry_data['imports'] as $import_key) { 99 if (isset($manifest[$import_key]) && is_array($manifest[$import_key])) {99 if (isset($manifest[$import_key])) { 100 100 $import_data = $manifest[$import_key]; 101 if (isset($import_data['css']) && is_array($import_data['css'])) { 102 foreach ($import_data['css'] as $css_file) { 103 $css_files[] = PULSE_CHAT_AI_PLUGIN_URL . 'dist/' . $css_file; 101 // Handle both array and string formats 102 if (is_array($import_data)) { 103 if (isset($import_data['css']) && is_array($import_data['css'])) { 104 foreach ($import_data['css'] as $css_file) { 105 $css_files[] = PULSE_CHAT_AI_PLUGIN_URL . 'dist/' . $css_file; 106 } 104 107 } 108 } else if (is_string($import_data) && strpos($import_data, '.css') !== false) { 109 // Direct CSS file reference 110 $css_files[] = PULSE_CHAT_AI_PLUGIN_URL . 'dist/' . $import_data; 105 111 } 106 112 } 107 113 } 108 114 } 115 } 116 117 // Also check for globals CSS file directly 118 $globals_css = PULSE_CHAT_AI_PLUGIN_URL . 'dist/assets/globals.css'; 119 if (file_exists(PULSE_CHAT_AI_PLUGIN_PATH . 'dist/assets/globals.css')) { 120 $css_files[] = $globals_css; 109 121 } 110 122 -
pulse-chat-ai/trunk/includes/class-license-manager.php
r3394690 r3395179 15 15 private $api_url = 'https://uhnaedqfygrqdptjngqb.supabase.co/functions/v1/license-check'; 16 16 17 // Product slug (must match the one used in admin) 17 // Product slug (must match EXACTLY the one used in admin/license creation) 18 // IMPORTANT: This must be identical character-by-character in both systems 19 // Changing this will cause 'product_mismatch' errors for all licenses 18 20 private $product_slug = 'pulse-chat-ai'; 19 21 … … 78 80 } 79 81 80 // Get current domain 82 // Get current domain normalized 81 83 $domain = $this->get_current_domain(); 84 85 // Normalize license key: convert to uppercase, trim, but keep format (with dashes) 86 $license_key_normalized = strtoupper(trim($license_key)); 82 87 83 88 // Build URL with query parameters 84 89 $url = add_query_arg(array( 85 'license' => $license_key ,90 'license' => $license_key_normalized, 86 91 'domain' => $domain, 87 92 'product' => $this->product_slug 88 93 ), $this->api_url); 94 95 // Debug logging 96 if (defined('WP_DEBUG') && WP_DEBUG) { 97 error_log('=== Validación de Licencia ==='); 98 error_log('License Key: ' . $license_key_normalized); 99 error_log('Product Slug: ' . $this->product_slug); 100 error_log('Site URL (raw): ' . home_url()); 101 error_log('Domain (normalized): ' . $domain); 102 error_log('API URL: ' . $url); 103 } 89 104 90 105 // Make request … … 96 111 // Check for connection errors 97 112 if (is_wp_error($response)) { 113 $error_message = $response->get_error_message(); 114 if (defined('WP_DEBUG') && WP_DEBUG) { 115 error_log('Error de conexión con API de licencias: ' . $error_message); 116 } 98 117 return array( 99 118 'valid' => false, 100 119 'reason' => 'connection_error', 101 120 'plan' => null, 102 'error' => $ response->get_error_message()121 'error' => $error_message 103 122 ); 104 123 } … … 108 127 $data = json_decode($body, true); 109 128 110 // Handle HTTP errors 129 // Debug logging 130 if (defined('WP_DEBUG') && WP_DEBUG) { 131 error_log('Response Status Code: ' . $status_code); 132 error_log('Response Body: ' . $body); 133 error_log('Response Data: ' . print_r($data, true)); 134 } 135 136 // Handle invalid JSON response 137 if (!$data || !is_array($data)) { 138 if (defined('WP_DEBUG') && WP_DEBUG) { 139 error_log('Error al parsear respuesta de API: ' . $body); 140 } 141 return array( 142 'valid' => false, 143 'reason' => 'invalid_response', 144 'plan' => null, 145 'error' => 'Invalid response from server' 146 ); 147 } 148 149 // Handle HTTP errors (non-200 status codes) 111 150 if ($status_code !== 200) { 151 // Check if it's a Supabase function not found error 152 if ($status_code === 404 && isset($data['code']) && $data['code'] === 'NOT_FOUND') { 153 if (defined('WP_DEBUG') && WP_DEBUG) { 154 error_log('ERROR: La función Edge de Supabase no está desplegada. Mensaje: ' . (isset($data['message']) ? $data['message'] : 'Function not found')); 155 } 156 return array( 157 'valid' => false, 158 'reason' => 'function_not_found', 159 'plan' => null, 160 'error' => 'La función de validación de licencias no está disponible. Por favor, contacta con soporte o verifica que la Edge Function esté desplegada en Supabase.' 161 ); 162 } 163 112 164 $reason = 'server_error'; 113 165 if (isset($data['reason'])) { 114 166 $reason = $data['reason']; 115 } 167 } else if ($status_code === 404) { 168 $reason = 'not_found'; 169 } 170 171 if (defined('WP_DEBUG') && WP_DEBUG) { 172 error_log('Licencia inválida. Razón: ' . $reason); 173 } 174 116 175 return array( 117 176 'valid' => false, 118 177 'reason' => $reason, 119 'plan' => null,178 'plan' => isset($data['plan']) ? $data['plan'] : null, 120 179 'error' => isset($data['message']) ? $data['message'] : 'Server error' 121 180 ); 122 181 } 123 182 124 // Save license data if valid 125 if (isset($data['valid']) && $data['valid'] && isset($data['plan'])) { 183 // Verify if license is valid: check reason === 'ok' and valid === true 184 if (isset($data['valid']) && $data['valid'] === true && isset($data['reason']) && $data['reason'] === 'ok') { 185 // License is valid - save license data 126 186 update_option($this->license_data_option, $data); 187 188 // Cache result for 24 hours 189 set_transient('pulse_chat_ai_license_check', $data, DAY_IN_SECONDS); 190 191 return $data; 127 192 } else { 193 // License is invalid - get reason from response 194 $reason = isset($data['reason']) ? $data['reason'] : 'server_error'; 195 196 if (defined('WP_DEBUG') && WP_DEBUG) { 197 error_log('Licencia inválida. Razón: ' . $reason); 198 } 199 128 200 // Clear license data if invalid 129 201 delete_option($this->license_data_option); 130 } 131 132 // Cache result for 24 hours 133 set_transient('pulse_chat_ai_license_check', $data, DAY_IN_SECONDS); 134 135 return $data; 202 203 // Return error response 204 return array( 205 'valid' => false, 206 'reason' => $reason, 207 'plan' => isset($data['plan']) ? $data['plan'] : null, 208 'error' => isset($data['message']) ? $data['message'] : 'License validation failed' 209 ); 210 } 211 } 212 213 /** 214 * Normalize domain according to API guide 215 * 216 * @param string $domain_or_url Domain or full URL to normalize 217 * @return string Normalized domain 218 */ 219 private function normalize_domain($domain_or_url) { 220 // 1. Eliminar protocolo (http://, https://) 221 $domain = preg_replace('#^https?://#', '', $domain_or_url); 222 223 // 2. Eliminar rutas y parámetros (todo después de /) 224 $domain = preg_replace('#/.*$#', '', $domain); 225 226 // 3. Eliminar www. al inicio 227 $domain = preg_replace('#^www\.#', '', $domain); 228 229 // 4. Convertir a minúsculas 230 $domain = strtolower($domain); 231 232 // 5. Eliminar espacios y trim 233 $domain = trim($domain); 234 235 // 6. IMPORTANTE: Eliminar puerto si existe (sin excepciones, ya que no validamos localhost) 236 // Ejemplo: "ejemplo.com:443" -> "ejemplo.com" 237 // Ejemplo: "ejemplo.com:8080" -> "ejemplo.com" 238 // Ejemplo: "localhost:8881" -> "localhost" 239 if (strpos($domain, ':') !== false) { 240 $domain = explode(':', $domain)[0]; 241 } 242 243 return $domain; 136 244 } 137 245 … … 140 248 */ 141 249 private function get_current_domain() { 142 $domain = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''; 143 144 // Remove www and protocol if exists 145 $domain = preg_replace('/^www\./', '', $domain); 146 147 // Remove port if exists 148 $domain = preg_replace('/:\d+$/', '', $domain); 149 150 return strtolower(trim($domain)); 250 // Use home_url() as recommended in the guide 251 $site_url = home_url(); 252 return $this->normalize_domain($site_url); 151 253 } 152 254 … … 207 309 public function get_error_message($reason) { 208 310 $messages = array( 311 'ok' => __('License is valid.', 'pulse-chat-ai'), 209 312 'no_license' => __('No active license. Please enter your license key.', 'pulse-chat-ai'), 210 313 'not_found' => __('License not found. Please verify that the key is correct.', 'pulse-chat-ai'), … … 213 316 'domain_mismatch' => __('This license is not valid for this domain.', 'pulse-chat-ai'), 214 317 'product_mismatch' => __('This license is not for this product.', 'pulse-chat-ai'), 318 'missing_params' => __('Missing required parameters.', 'pulse-chat-ai'), 215 319 'connection_error' => __('Connection error. Please check your internet connection.', 'pulse-chat-ai'), 216 'server_error' => __('Server error. Please try again later.', 'pulse-chat-ai') 320 'server_error' => __('Server error. Please try again later.', 'pulse-chat-ai'), 321 'invalid_response' => __('Invalid response from server.', 'pulse-chat-ai'), 322 'function_not_found' => __('The license validation function is not available. Please contact support or verify that the Supabase Edge Function is deployed.', 'pulse-chat-ai') 217 323 ); 218 324 -
pulse-chat-ai/trunk/pulse-chat-ai.php
r3394690 r3395179 4 4 * Plugin URI: https://pulsechatai.com 5 5 * Description: AI-powered ChatGPT 5 chat assistant for WordPress. Perfect for customer support and engagement. 6 * Version: 2.2. 06 * Version: 2.2.3 7 7 * Requires at least: 5.0 8 8 * Requires PHP: 7.4 … … 22 22 23 23 // Define plugin constants 24 define('PULSE_CHAT_AI_VERSION', '2.2. 0');24 define('PULSE_CHAT_AI_VERSION', '2.2.3'); 25 25 define('PULSE_CHAT_AI_PLUGIN_URL', plugin_dir_url(__FILE__)); 26 26 define('PULSE_CHAT_AI_PLUGIN_PATH', plugin_dir_path(__FILE__)); -
pulse-chat-ai/trunk/readme.txt
r3394690 r3395179 6 6 Tested up to: 6.8 7 7 Requires PHP: 7.4 8 Stable tag: 2.2. 08 Stable tag: 2.2.3 9 9 License: GPLv2 or later 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 127 127 128 128 == Changelog == 129 130 = 2.2.3 - January 2026 = 131 * FIXED: Domain normalization now always removes ports (no localhost exception) 132 * FIXED: License validation domain mismatch issues resolved 133 * IMPROVED: Domain normalization aligned with Supabase license system 134 * IMPROVED: Added important comments about product_slug matching requirements 129 135 130 136 = 2.2.0 - January 2026 =
Note: See TracChangeset
for help on using the changeset viewer.