From 50864bdb6ae303f1620a2523c060d9d9ae12b7f3 Mon Sep 17 00:00:00 2001 From: Rodrigue Tusse Date: Thu, 8 Aug 2024 13:59:44 +0200 Subject: [PATCH 01/10] Use get_title() for content_name to match catalog name. --- facebook-commerce-events-tracker.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/facebook-commerce-events-tracker.php b/facebook-commerce-events-tracker.php index cc4139dbb..c2c90be5c 100644 --- a/facebook-commerce-events-tracker.php +++ b/facebook-commerce-events-tracker.php @@ -583,7 +583,7 @@ public function inject_add_to_cart_event( $cart_item_key, $product_id, $quantity 'event_name' => 'AddToCart', 'custom_data' => array( 'content_ids' => wp_json_encode( \WC_Facebookcommerce_Utils::get_fb_content_ids( $product ) ), - 'content_name' => $product->get_name(), + 'content_name' => $product->get_title(), 'content_type' => 'product', 'contents' => wp_json_encode( array( @@ -655,7 +655,7 @@ public function add_add_to_cart_event_fragment( $fragments ) { $params = array( 'content_ids' => wp_json_encode( \WC_Facebookcommerce_Utils::get_fb_content_ids( $product ) ), - 'content_name' => $product->get_name(), + 'content_name' => $product->get_title(), 'content_type' => 'product', 'contents' => wp_json_encode( array( @@ -846,7 +846,7 @@ public function inject_purchase_event( $order_id ) { if ( $product ) { $product_ids[] = \WC_Facebookcommerce_Utils::get_fb_content_ids( $product ); - $product_names[] = $product->get_name(); + $product_names[] = $product->get_title(); if ( 'product_group' !== $content_type && $product->is_type( 'variable' ) ) { $content_type = 'product_group'; @@ -1061,7 +1061,7 @@ private function get_cart_content_names() { if ( isset( $item['data'] ) && $item['data'] instanceof \WC_Product ) { - $product_names[] = $item['data']->get_name(); + $product_names[] = $item['data']->get_title(); } } } From 3a8e4b83f6a21b3b7cae74cff3f1ef59e61e9c8e Mon Sep 17 00:00:00 2001 From: Rodrigue Tusse Date: Thu, 8 Aug 2024 14:20:19 +0200 Subject: [PATCH 02/10] Clean up strings. --- facebook-commerce-events-tracker.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/facebook-commerce-events-tracker.php b/facebook-commerce-events-tracker.php index c2c90be5c..35ebea052 100644 --- a/facebook-commerce-events-tracker.php +++ b/facebook-commerce-events-tracker.php @@ -517,7 +517,7 @@ public function inject_view_content_event() { $event_data = array( 'event_name' => 'ViewContent', 'custom_data' => array( - 'content_name' => $product->get_title(), + 'content_name' => \WC_Facebookcommerce_Utils::clean_string( $product->get_title() ), 'content_ids' => wp_json_encode( \WC_Facebookcommerce_Utils::get_fb_content_ids( $product ) ), 'content_type' => $content_type, 'contents' => wp_json_encode( @@ -583,7 +583,7 @@ public function inject_add_to_cart_event( $cart_item_key, $product_id, $quantity 'event_name' => 'AddToCart', 'custom_data' => array( 'content_ids' => wp_json_encode( \WC_Facebookcommerce_Utils::get_fb_content_ids( $product ) ), - 'content_name' => $product->get_title(), + 'content_name' => \WC_Facebookcommerce_Utils::clean_string( $product->get_title() ), 'content_type' => 'product', 'contents' => wp_json_encode( array( @@ -655,7 +655,7 @@ public function add_add_to_cart_event_fragment( $fragments ) { $params = array( 'content_ids' => wp_json_encode( \WC_Facebookcommerce_Utils::get_fb_content_ids( $product ) ), - 'content_name' => $product->get_title(), + 'content_name' => \WC_Facebookcommerce_Utils::clean_string( $product->get_title() ), 'content_type' => 'product', 'contents' => wp_json_encode( array( @@ -846,7 +846,7 @@ public function inject_purchase_event( $order_id ) { if ( $product ) { $product_ids[] = \WC_Facebookcommerce_Utils::get_fb_content_ids( $product ); - $product_names[] = $product->get_title(); + $product_names[] = \WC_Facebookcommerce_Utils::clean_string( $product->get_title() ); if ( 'product_group' !== $content_type && $product->is_type( 'variable' ) ) { $content_type = 'product_group'; From 28ccf99ff0cb67e01a9651b73058e2386cfb16b1 Mon Sep 17 00:00:00 2001 From: Rodrigue Tusse Date: Thu, 8 Aug 2024 14:21:19 +0200 Subject: [PATCH 03/10] Clean up strings. --- facebook-commerce-events-tracker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/facebook-commerce-events-tracker.php b/facebook-commerce-events-tracker.php index 35ebea052..2af4c6fac 100644 --- a/facebook-commerce-events-tracker.php +++ b/facebook-commerce-events-tracker.php @@ -1061,7 +1061,7 @@ private function get_cart_content_names() { if ( isset( $item['data'] ) && $item['data'] instanceof \WC_Product ) { - $product_names[] = $item['data']->get_title(); + $product_names[] = \WC_Facebookcommerce_Utils::clean_string( $item['data']->get_title() ); } } } From 8a57e6db0c9c2954ee857ceada14de9f6d9c3077 Mon Sep 17 00:00:00 2001 From: Dima <9010963+message-dimke@users.noreply.github.com> Date: Sun, 11 Aug 2024 17:08:17 +0300 Subject: [PATCH 04/10] - Redoing how we fetch access tokens from WooCommerce Connect Server. - Securing code to access token exchange with a nonce. --- includes/Handlers/Connection.php | 43 ++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/includes/Handlers/Connection.php b/includes/Handlers/Connection.php index 263e9b0b6..12ccd8f2f 100644 --- a/includes/Handlers/Connection.php +++ b/includes/Handlers/Connection.php @@ -36,6 +36,8 @@ class Connection { /** @var string WooCommerce connection proxy URL */ const PROXY_URL = 'https://api.woocommerce.com/integrations/auth/facebook/'; + const PROXY_TOKEN_EXCHANGE_URL = 'https://api.woocommerce.com/integrations/exchange/facebook/'; + /** @var string WooCommerce connection for APP Store login URL */ const APP_STORE_LOGIN_URL = 'https://api.woocommerce.com/integrations/app-store-login/facebook/'; @@ -48,6 +50,8 @@ class Connection { /** @var string the action callback for the connection */ const ACTION_CONNECT = 'wc_facebook_connect'; + const ACTION_EXCHANGE = 'wc_facebook_exchange'; + /** @var string the action callback for the disconnection */ const ACTION_DISCONNECT = 'wc_facebook_disconnect'; @@ -246,14 +250,43 @@ public function handle_connect() { if ( empty( $_GET['nonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_GET['nonce'] ) ), self::ACTION_CONNECT ) ) { throw new ApiException( 'Invalid nonce' ); } - $is_error = ! empty( $_GET['err'] ) ? true : false; - $error_code = ! empty( $_GET['err_code'] ) ? stripslashes( wc_clean( wp_unslash( $_GET['err_code'] ) ) ) : ''; - $merchant_access_token = ! empty( $_GET['merchant_access_token'] ) ? wc_clean( wp_unslash( $_GET['merchant_access_token'] ) ) : ''; - $system_user_access_token = ! empty( $_GET['system_user_access_token'] ) ? wc_clean( wp_unslash( $_GET['system_user_access_token'] ) ) : ''; - $system_user_id = ! empty( $_GET['system_user_id'] ) ? wc_clean( wp_unslash( $_GET['system_user_id'] ) ) : ''; + + $is_error = ! empty( $_GET['err'] ) ? true : false; + $error_code = ! empty( $_GET['err_code'] ) ? stripslashes( wc_clean( wp_unslash( $_GET['err_code'] ) ) ) : ''; if ( $is_error && $error_code ) { throw new ConnectApiException( $error_code ); } + + $facebook_auth_code = $_GET['code'] ?? ''; + if ( empty( $facebook_auth_code ) ) { + throw new ApiException( 'Facebook auth code is missing.' ); + } + + $response = wp_safe_remote_get( + self::PROXY_TOKEN_EXCHANGE_URL, + [ + 'nonce' => wp_create_nonce( self::ACTION_EXCHANGE ), + 'code' => $facebook_auth_code, + 'external_business_id' => $this->get_external_business_id(), + 'type' => self::AUTH_TYPE_STANDARD, + ] + ); + + if ( is_wp_error( $response ) ) { + throw new ApiException( 'WooCommerce Connect Server token exchange has failed.' ); + } + + $token_data = json_decode( wp_remote_retrieve_body( $response ), true ); + + // Check that request was initiated from the server. + if ( ! wp_verify_nonce( $token_data['nonce'] ?? '', self::ACTION_EXCHANGE ) ) { + throw new ApiException( 'Exchange nonce is not valid.' ); + } + + $merchant_access_token = ! empty( $token_data['merchant_access_token'] ) ? wc_clean( wp_unslash( $token_data['merchant_access_token'] ) ) : ''; + $system_user_access_token = ! empty( $token_data['system_user_access_token'] ) ? wc_clean( wp_unslash( $token_data['system_user_access_token'] ) ) : ''; + $system_user_id = ! empty( $token_data['system_user_id'] ) ? wc_clean( wp_unslash( $token_data['system_user_id'] ) ) : ''; + if ( ! $merchant_access_token ) { throw new ApiException( 'Access token is missing' ); } From 9694df0b376de1e9ec4d7027a48cda89ec9e72db Mon Sep 17 00:00:00 2001 From: Rodrigue Tusse Date: Tue, 13 Aug 2024 19:46:02 +0200 Subject: [PATCH 05/10] Add timeout param to exchange request and other minor fixes. --- includes/Handlers/Connection.php | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/includes/Handlers/Connection.php b/includes/Handlers/Connection.php index 12ccd8f2f..a32894876 100644 --- a/includes/Handlers/Connection.php +++ b/includes/Handlers/Connection.php @@ -251,25 +251,36 @@ public function handle_connect() { throw new ApiException( 'Invalid nonce' ); } - $is_error = ! empty( $_GET['err'] ) ? true : false; + $is_error = ! empty( $_GET['err'] ); $error_code = ! empty( $_GET['err_code'] ) ? stripslashes( wc_clean( wp_unslash( $_GET['err_code'] ) ) ) : ''; if ( $is_error && $error_code ) { throw new ConnectApiException( $error_code ); } $facebook_auth_code = $_GET['code'] ?? ''; + $state = $_GET['state'] ?? ''; if ( empty( $facebook_auth_code ) ) { throw new ApiException( 'Facebook auth code is missing.' ); } - $response = wp_safe_remote_get( - self::PROXY_TOKEN_EXCHANGE_URL, - [ + if ( empty( $state ) ) { + throw new ApiException( 'Missing state query parameter.' ); + } + + $parameters_string = '?' . http_build_query( array( 'nonce' => wp_create_nonce( self::ACTION_EXCHANGE ), 'code' => $facebook_auth_code, 'external_business_id' => $this->get_external_business_id(), 'type' => self::AUTH_TYPE_STANDARD, - ] + 'state' => $state, + ) ); + + $request_url = self::PROXY_TOKEN_EXCHANGE_URL . $parameters_string; + $response = wp_safe_remote_get( + $request_url, + array( + 'timeout' => 60, + ) ); if ( is_wp_error( $response ) ) { @@ -278,6 +289,10 @@ public function handle_connect() { $token_data = json_decode( wp_remote_retrieve_body( $response ), true ); + if ( isset( $token_data[ 'status' ] ) && $token_data[ 'status' ] === 500 ) { + throw new ApiException( 'WooCommerce Connect Server token exchange has failed.' ); + } + // Check that request was initiated from the server. if ( ! wp_verify_nonce( $token_data['nonce'] ?? '', self::ACTION_EXCHANGE ) ) { throw new ApiException( 'Exchange nonce is not valid.' ); From a62d3cb7416dc5bf2f6e18123ed03e76e380a8f8 Mon Sep 17 00:00:00 2001 From: Rodrigue Tusse Date: Wed, 14 Aug 2024 13:47:39 +0200 Subject: [PATCH 06/10] Call v2 endpoints. --- includes/Handlers/Connection.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/Handlers/Connection.php b/includes/Handlers/Connection.php index a32894876..db65d0857 100644 --- a/includes/Handlers/Connection.php +++ b/includes/Handlers/Connection.php @@ -34,9 +34,9 @@ class Connection { const OAUTH_URL = 'https://facebook.com/dialog/oauth'; /** @var string WooCommerce connection proxy URL */ - const PROXY_URL = 'https://api.woocommerce.com/integrations/auth/facebook/'; + const PROXY_URL = 'https://api.woocommerce.com/integrations/v2/auth/facebook/'; - const PROXY_TOKEN_EXCHANGE_URL = 'https://api.woocommerce.com/integrations/exchange/facebook/'; + const PROXY_TOKEN_EXCHANGE_URL = 'https://api.woocommerce.com/integrations/v2/exchange/facebook/'; /** @var string WooCommerce connection for APP Store login URL */ const APP_STORE_LOGIN_URL = 'https://api.woocommerce.com/integrations/app-store-login/facebook/'; From 43b0e00147196a0cb94881307f06bc1c8f9616d4 Mon Sep 17 00:00:00 2001 From: Rodrigue Tusse Date: Tue, 20 Aug 2024 06:39:17 +0200 Subject: [PATCH 07/10] Address review feedback. --- includes/Handlers/Connection.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/includes/Handlers/Connection.php b/includes/Handlers/Connection.php index db65d0857..f53c87d5d 100644 --- a/includes/Handlers/Connection.php +++ b/includes/Handlers/Connection.php @@ -34,15 +34,15 @@ class Connection { const OAUTH_URL = 'https://facebook.com/dialog/oauth'; /** @var string WooCommerce connection proxy URL */ - const PROXY_URL = 'https://api.woocommerce.com/integrations/v2/auth/facebook/'; + const PROXY_URL = 'https://wcs.jurassic.tube/integrations/v2/auth/facebook/'; - const PROXY_TOKEN_EXCHANGE_URL = 'https://api.woocommerce.com/integrations/v2/exchange/facebook/'; + const PROXY_TOKEN_EXCHANGE_URL = 'https://wcs.jurassic.tube/integrations/v2/exchange/facebook/'; /** @var string WooCommerce connection for APP Store login URL */ - const APP_STORE_LOGIN_URL = 'https://api.woocommerce.com/integrations/app-store-login/facebook/'; + const APP_STORE_LOGIN_URL = 'https://wcs.jurassic.tube/integrations/app-store-login/facebook/'; /** @var string WooCommerce connection authentication URL */ - const CONNECTION_AUTHENTICATION_URL = 'https://api.woocommerce.com/integrations/auth/facebookcommerce/'; + const CONNECTION_AUTHENTICATION_URL = 'https://wcs.jurassic.tube/integrations/auth/facebookcommerce/'; /** @var string the Standard Auth type */ const AUTH_TYPE_STANDARD = 'standard'; @@ -258,11 +258,11 @@ public function handle_connect() { } $facebook_auth_code = $_GET['code'] ?? ''; - $state = $_GET['state'] ?? ''; if ( empty( $facebook_auth_code ) ) { throw new ApiException( 'Facebook auth code is missing.' ); } + $state = $_GET['state'] ?? ''; if ( empty( $state ) ) { throw new ApiException( 'Missing state query parameter.' ); } @@ -276,7 +276,7 @@ public function handle_connect() { ) ); $request_url = self::PROXY_TOKEN_EXCHANGE_URL . $parameters_string; - $response = wp_safe_remote_get( + $response = wp_safe_remote_get( $request_url, array( 'timeout' => 60, @@ -298,9 +298,9 @@ public function handle_connect() { throw new ApiException( 'Exchange nonce is not valid.' ); } - $merchant_access_token = ! empty( $token_data['merchant_access_token'] ) ? wc_clean( wp_unslash( $token_data['merchant_access_token'] ) ) : ''; - $system_user_access_token = ! empty( $token_data['system_user_access_token'] ) ? wc_clean( wp_unslash( $token_data['system_user_access_token'] ) ) : ''; - $system_user_id = ! empty( $token_data['system_user_id'] ) ? wc_clean( wp_unslash( $token_data['system_user_id'] ) ) : ''; + $merchant_access_token = wc_clean( wp_unslash( $token_data['merchant_access_token'] ?? '' ) ) ; + $system_user_access_token = wc_clean( wp_unslash( $token_data['system_user_access_token'] ?? '' ) ) ; + $system_user_id = wc_clean( wp_unslash( $token_data['system_user_id'] ?? '' ) ) ; if ( ! $merchant_access_token ) { throw new ApiException( 'Access token is missing' ); From 9bf7f6c35a907d2cc6e9c48331173238d078cc0a Mon Sep 17 00:00:00 2001 From: Rodrigue Tusse Date: Tue, 20 Aug 2024 11:28:34 +0200 Subject: [PATCH 08/10] remove test url. --- includes/Handlers/Connection.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/Handlers/Connection.php b/includes/Handlers/Connection.php index f53c87d5d..4cf5217de 100644 --- a/includes/Handlers/Connection.php +++ b/includes/Handlers/Connection.php @@ -34,15 +34,15 @@ class Connection { const OAUTH_URL = 'https://facebook.com/dialog/oauth'; /** @var string WooCommerce connection proxy URL */ - const PROXY_URL = 'https://wcs.jurassic.tube/integrations/v2/auth/facebook/'; + const PROXY_URL = 'https://api.woocommerce.com/integrations/v2/auth/facebook/'; - const PROXY_TOKEN_EXCHANGE_URL = 'https://wcs.jurassic.tube/integrations/v2/exchange/facebook/'; + const PROXY_TOKEN_EXCHANGE_URL = 'https://api.woocommerce.com/integrations/v2/exchange/facebook/'; /** @var string WooCommerce connection for APP Store login URL */ - const APP_STORE_LOGIN_URL = 'https://wcs.jurassic.tube/integrations/app-store-login/facebook/'; + const APP_STORE_LOGIN_URL = 'https://api.woocommerce.com/integrations/app-store-login/facebook/'; /** @var string WooCommerce connection authentication URL */ - const CONNECTION_AUTHENTICATION_URL = 'https://wcs.jurassic.tube/integrations/auth/facebookcommerce/'; + const CONNECTION_AUTHENTICATION_URL = 'https://api.woocommerce.com/integrations/auth/facebookcommerce/'; /** @var string the Standard Auth type */ const AUTH_TYPE_STANDARD = 'standard'; From 1173d4c4fa1db720c841be37f4853fd3e5f3ba4b Mon Sep 17 00:00:00 2001 From: Kader Ibrahim S Date: Tue, 3 Sep 2024 21:23:58 +0530 Subject: [PATCH 09/10] woorelease: Product version bump update --- facebook-for-woocommerce.php | 4 ++-- package-lock.json | 2 +- package.json | 2 +- readme.txt | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/facebook-for-woocommerce.php b/facebook-for-woocommerce.php index cf7dbe86e..f55d1c709 100644 --- a/facebook-for-woocommerce.php +++ b/facebook-for-woocommerce.php @@ -11,7 +11,7 @@ * Description: Grow your business on Facebook! Use this official plugin to help sell more of your products using Facebook. After completing the setup, you'll be ready to create ads that promote your products and you can also create a shop section on your Page where customers can browse your products on Facebook. * Author: Facebook * Author URI: https://www.facebook.com/ - * Version: 3.2.7 + * Version: 3.2.8 * Requires at least: 5.6 * Requires PHP: 7.4 * Text Domain: facebook-for-woocommerce @@ -49,7 +49,7 @@ class WC_Facebook_Loader { /** * @var string the plugin version. This must be in the main plugin file to be automatically bumped by Woorelease. */ - const PLUGIN_VERSION = '3.2.7'; // WRCS: DEFINED_VERSION. + const PLUGIN_VERSION = '3.2.8'; // WRCS: DEFINED_VERSION. // Minimum PHP version required by this plugin. const MINIMUM_PHP_VERSION = '7.4.0'; diff --git a/package-lock.json b/package-lock.json index 4a50adbd0..1f637a64f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "facebook-for-woocommerce", - "version": "3.2.7", + "version": "3.2.8", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/package.json b/package.json index 6efcb1886..a3f046bfc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "facebook-for-woocommerce", - "version": "3.2.7", + "version": "3.2.8", "author": "Facebook", "homepage": "https://woocommerce.com/products/facebook/", "license": "GPL-2.0", diff --git a/readme.txt b/readme.txt index 0e374373b..172db79d1 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: facebook, automattic, woothemes Tags: facebook, woocommerce, marketing, product catalog feed, pixel Requires at least: 5.6 Tested up to: 6.6 -Stable tag: 3.2.7 +Stable tag: 3.2.8 Requires PHP: 7.4 MySQL: 5.6 or greater License: GPLv2 or later From d4cc6966b5f259950de3ec36ae842bed6353ef7f Mon Sep 17 00:00:00 2001 From: Kader Ibrahim S Date: Tue, 3 Sep 2024 21:24:03 +0530 Subject: [PATCH 10/10] woorelease: Changelog update --- changelog.txt | 4 ++++ readme.txt | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/changelog.txt b/changelog.txt index 6e49951e1..368cd038d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,9 @@ *** Facebook for WooCommerce Changelog *** += 3.2.8 - 2024-09-03 = +* Update - Access Token retrieval procedure. +* Update - Use get_title() for content_name to match catalog name. + = 3.2.7 - 2024-08-13 = * Dev - Updated `phpcs` ruleset. * Fix - Update failing due to undefined constant error in Lifecycle. diff --git a/readme.txt b/readme.txt index 172db79d1..5a3246a77 100644 --- a/readme.txt +++ b/readme.txt @@ -40,6 +40,10 @@ When opening a bug on GitHub, please give us as many details as possible. == Changelog == += 3.2.8 - 2024-09-03 = +* Update - Access Token retrieval procedure. +* Update - Use get_title() for content_name to match catalog name. + = 3.2.7 - 2024-08-13 = * Dev - Updated `phpcs` ruleset. * Fix - Update failing due to undefined constant error in Lifecycle.