'POST', 'callback' => [$this, 'get_token'], 'permission_callback' => [$this, 'verify_request'], ] ); register_rest_route( self::API_NAMESPACE, '/verify', [ 'methods' => 'POST', 'callback' => [$this, 'verify_token'], 'permission_callback' => [$this, 'verify_request'], ] ); register_rest_route( self::API_NAMESPACE, '/refresh', [ 'methods' => 'POST', 'callback' => [$this, 'refresh_token'], 'permission_callback' => [$this, 'verify_request'], ] ); error_log('EveAI REST routes Registered'); } public function verify_request(\WP_REST_Request $request): bool { // error_log('Verifying EveAI request: ' . print_r([ // 'route' => $request->get_route(), // 'headers' => $request->get_headers(), // 'params' => $request->get_params() // ], true)); // Verify nonce $nonce = $request->get_header('X-WP-Nonce'); if (!wp_verify_nonce($nonce, 'wp_rest')) { error_log('EveAI nonce verification failed'); return false; } // Verify origin $origin = $request->get_header('origin'); if (!$this->verify_origin($origin)) { return false; } return true; } public function get_token(\WP_REST_Request $request) { try { $settings = get_option('eveai_chat_settings'); if (empty($settings['tenant_id']) || empty($settings['api_key'])) { return new \WP_Error( 'configuration_error', 'EveAI Chat is not properly configured.', ['status' => 500] ); } $auth_url = rtrim($settings['auth_url'], '/'); $token_endpoint = '/api/v1/auth/token'; $full_url = $auth_url . $token_endpoint; error_log('Attempting to get token from: ' . $full_url); // Get decrypted API key $api_key = Security::decrypt_api_key($settings['api_key']); $response = wp_remote_post($full_url, [ 'headers' => [ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ], 'body' => json_encode([ 'tenant_id' => $settings['tenant_id'], 'api_key' => $api_key ]) ]); error_log('EveAI API Response: ' . print_r($response, true)); if (is_wp_error($response)) { throw new \Exception($response->get_error_message()); } $body = json_decode(wp_remote_retrieve_body($response), true); error_log('Token response body: ' . print_r($body, true)); // Add this for debugging if (!isset($body['access_token'])) { throw new \Exception('No token in response'); } return new \WP_REST_Response($body, 200); } catch (\Exception $e) { error_log('EveAI token error: ' . $e->getMessage()); return new \WP_Error( 'token_error', $e->getMessage(), ['status' => 500] ); } } public function verify_token(\WP_REST_Request $request) { try { $token = $request->get_header('Authorization'); if (!$token) { throw new \Exception('No token provided'); } $settings = get_option('eveai_chat_settings'); $response = wp_remote_post($settings['auth_url'] . '/auth/verify', [ 'headers' => ['Authorization' => $token] ]); if (is_wp_error($response)) { throw new \Exception($response->get_error_message()); } $body = json_decode(wp_remote_retrieve_body($response), true); return new \WP_REST_Response($body, 200); } catch (\Exception $e) { return new \WP_Error( 'verify_error', $e->getMessage(), ['status' => 401] ); } } public function refresh_token(\WP_REST_Request $request) { try { $token = $request->get_header('Authorization'); if (!$token) { throw new \Exception('No token provided'); } $settings = get_option('eveai_chat_settings'); $response = wp_remote_post($settings['auth_url'] . '/auth/refresh', [ 'headers' => ['Authorization' => $token] ]); if (is_wp_error($response)) { throw new \Exception($response->get_error_message()); } $body = json_decode(wp_remote_retrieve_body($response), true); return new \WP_REST_Response($body, 200); } catch (\Exception $e) { return new \WP_Error( 'refresh_error', $e->getMessage(), ['status' => 401] ); } } private function verify_origin($origin): bool { if (empty($origin)) { return false; } $site_url = parse_url(get_site_url(), PHP_URL_HOST); $origin_host = parse_url($origin, PHP_URL_HOST); return $origin_host === $site_url; } }