From 4875ec30d05e30996b94f4b88f963c9ffe87280a Mon Sep 17 00:00:00 2001 From: chuccv Date: Wed, 5 Oct 2022 17:12:49 +0700 Subject: [PATCH 1/9] - Added Deletion Data for Facebook --- Block/System/RedirectUrl.php | 5 +- Controller/Social/DataDeletion.php | 140 +++++++++++++++++++++++++++++ Helper/Social.php | 36 +++++++- etc/adminhtml/system.xml | 7 ++ 4 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 Controller/Social/DataDeletion.php diff --git a/Block/System/RedirectUrl.php b/Block/System/RedirectUrl.php index 7ff3ff4..1e25f67 100755 --- a/Block/System/RedirectUrl.php +++ b/Block/System/RedirectUrl.php @@ -66,7 +66,10 @@ protected function _getElementHtml(AbstractElement $element) { $elementId = explode('_', $element->getHtmlId()); $redirectUrl = $this->socialHelper->getAuthUrl($elementId[1]); - $html = ''; + if ($elementId[2] === 'delete') { + $redirectUrl = $this->socialHelper->getDeleteDataUrl($elementId[1]); + } + $html = ''; return $html; } diff --git a/Controller/Social/DataDeletion.php b/Controller/Social/DataDeletion.php new file mode 100644 index 0000000..32a6f40 --- /dev/null +++ b/Controller/Social/DataDeletion.php @@ -0,0 +1,140 @@ +getRequest()->getParams(); + + if (isset($param['type']) && $param['type'] === 'facebook') { + $signed_request = $param['signed_request']; + $data = $this->parseSignedRequest($signed_request); + if ($data && $data['user_id']) { + $this->apiObject->load($data['user_id'], 'social_id'); + try { + $this->apiObject->delete(); + } catch (\Exception $e) { + return $this->getResponse()->representJson(''); + } + } + $response = [ + 'url' => $this->getStore()->getBaseUrl() . "/sociallogin/social/datadeletion/type/facebook?id={$data['algorithm']}", + 'confirmation_code' => $data['algorithm'], + ]; + $response = json_encode($response); + + return $this->getResponse()->representJson($response); + } + + return $this->getResponse()->representJson(''); + + } + + /** + * @param string $signedRequest + * + * @return mixed|null + */ + public function parseSignedRequest($signedRequest) + { + [$encoded_sig, $payload] = explode('.', $signedRequest, 2); + + $this->apiHelper->setType('facebook'); + $secret = $this->apiHelper->getAppSecret(); // Use your app secret here + + // decode the data + $sig = $this->base64UrlDecode($encoded_sig); + $data = json_decode($this->base64UrlDecode($payload), true); + + // confirm the signature + $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true); + if ($sig !== $expected_sig) { + return null; + } + + return $data; + } + + /** + * @param $input + * + * @return false|string + */ + public function base64UrlDecode($input) + { + return base64_decode(strtr($input, '-_', '+/')); + } +} diff --git a/Helper/Social.php b/Helper/Social.php index cb51295..38f8a26 100644 --- a/Helper/Social.php +++ b/Helper/Social.php @@ -195,6 +195,20 @@ public function getAuthUrl($type) return $authUrl . ($param ? (strpos($authUrl, '?') ? '&' : '?') . $param : ''); } + /** + * @param $type + * + * @return string + * @throws LocalizedException + */ + public function getDeleteDataUrl($type) + { + $authUrl = $this->getBaseDelete(); + $type = $this->setType($type); + + return $authUrl . 'type/' . strtolower($type); + } + /** * @return string * @throws LocalizedException @@ -208,7 +222,25 @@ public function getBaseAuthUrl() [ '_nosid' => true, '_scope' => $storeId, - '_secure' => true + '_secure' => true, + ] + ); + } + + /** + * @return string + * @throws LocalizedException + */ + public function getBaseDelete() + { + $storeId = $this->getScopeUrl(); + + return $this->_getUrl( + 'sociallogin/social/datadeletion', + [ + '_nosid' => true, + '_scope' => $storeId, + '_secure' => true, ] ); } @@ -244,7 +276,7 @@ public function getSocialTypesArray() 'vkontakte' => 'Vkontakte', 'github' => 'Github', 'live' => 'Live', - 'zalo' => 'Zalo' + 'zalo' => 'Zalo', ]; } } diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index b930c3b..18c3101 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -157,6 +157,13 @@ 1 + + Mageplaza\SocialLogin\Block\System\RedirectUrl + + + 1 + + From 0cdc70f392d35a0d726d3ac7bca3e35be00a25a8 Mon Sep 17 00:00:00 2001 From: chuccv Date: Thu, 6 Oct 2022 10:21:57 +0700 Subject: [PATCH 2/9] [DeletionDataFacebook] - add Custom CsrfValidator. --- Controller/Social/DataDeletion.php | 16 +++----- Plugin/CsrfValidator.php | 66 ++++++++++++++++++++++++++++++ etc/frontend/di.xml | 3 ++ 3 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 Plugin/CsrfValidator.php diff --git a/Controller/Social/DataDeletion.php b/Controller/Social/DataDeletion.php index 32a6f40..9a56bc6 100644 --- a/Controller/Social/DataDeletion.php +++ b/Controller/Social/DataDeletion.php @@ -30,16 +30,16 @@ use Magento\Framework\Controller\Result\RawFactory; use Magento\Framework\Controller\ResultInterface; use Magento\Store\Model\StoreManagerInterface; +use Mageplaza\Core\Helper\AbstractData; use Mageplaza\SocialLogin\Helper\Social as SocialHelper; use Mageplaza\SocialLogin\Model\Social; /** - * Class DeleteSocial + * Class DataDeletion * @package Mageplaza\SocialLogin\Controller\Social */ class DataDeletion extends AbstractSocial { - /** * @type \Mageplaza\SocialLogin\Helper\Social */ @@ -94,7 +94,7 @@ public function execute() 'url' => $this->getStore()->getBaseUrl() . "/sociallogin/social/datadeletion/type/facebook?id={$data['algorithm']}", 'confirmation_code' => $data['algorithm'], ]; - $response = json_encode($response); + $response = AbstractData::jsonEncode($response); return $this->getResponse()->representJson($response); } @@ -113,13 +113,9 @@ public function parseSignedRequest($signedRequest) [$encoded_sig, $payload] = explode('.', $signedRequest, 2); $this->apiHelper->setType('facebook'); - $secret = $this->apiHelper->getAppSecret(); // Use your app secret here - - // decode the data - $sig = $this->base64UrlDecode($encoded_sig); - $data = json_decode($this->base64UrlDecode($payload), true); - - // confirm the signature + $secret = $this->apiHelper->getAppSecret(); + $sig = $this->base64UrlDecode($encoded_sig); + $data = json_decode($this->base64UrlDecode($payload), true); $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true); if ($sig !== $expected_sig) { return null; diff --git a/Plugin/CsrfValidator.php b/Plugin/CsrfValidator.php new file mode 100644 index 0000000..ebb6d00 --- /dev/null +++ b/Plugin/CsrfValidator.php @@ -0,0 +1,66 @@ +_helperData = $helperData; + } + + /** + * @param \Magento\Framework\App\Request\CsrfValidator $subject + * @param RequestInterface $request + * @param ActionInterface $action + */ + public function aroundValidate( + \Magento\Framework\App\Request\CsrfValidator $subject, + callable $proceed, + RequestInterface $request, + ActionInterface $action + ) { + if ($request->getFullActionName() === 'sociallogin_social_datadeletion') { + return true; + } + + return $proceed(); + } +} diff --git a/etc/frontend/di.xml b/etc/frontend/di.xml index e953e60..3f145ea 100644 --- a/etc/frontend/di.xml +++ b/etc/frontend/di.xml @@ -24,4 +24,7 @@ + + + From ea1ff510122e238ec2791981e1f75d8b8aea378d Mon Sep 17 00:00:00 2001 From: chuccv Date: Fri, 7 Oct 2022 09:41:58 +0700 Subject: [PATCH 3/9] [DeletionDataFacebook] - add Show Status Data Deletion when User click "ViewStatus" in FacebookProvider. --- Block/DataDeletion/DeleteData.php | 103 ++++++++++++++++++ Controller/Social/DataDeletion.php | 59 +++++++--- Plugin/CsrfValidator.php | 20 +--- view/frontend/layout/cms_index_index.xml | 31 ++++++ .../templates/data_deletion/delete_data.phtml | 48 ++++++++ 5 files changed, 232 insertions(+), 29 deletions(-) create mode 100644 Block/DataDeletion/DeleteData.php create mode 100644 view/frontend/layout/cms_index_index.xml create mode 100755 view/frontend/templates/data_deletion/delete_data.phtml diff --git a/Block/DataDeletion/DeleteData.php b/Block/DataDeletion/DeleteData.php new file mode 100644 index 0000000..cba4e06 --- /dev/null +++ b/Block/DataDeletion/DeleteData.php @@ -0,0 +1,103 @@ +_helper = $helper; + $this->_socialHelper = $socialHelper; + + parent::__construct($context, $data); + } + + /** + * @return DataHelper + */ + public function helper() + { + return $this->_helper; + } + + /** + * + */ + public function isShowConfirm() + { + $type = $this->getRequest()->getParam('type'); + try { + if ($type && $this->_socialHelper->getDeleteDataUrl($type)) { + return true; + } + } catch (LocalizedException $e) { + + return false; + } + + return false; + } + + /** + * @return string + */ + public function getStoreName() + { + try { + return $this->_storeManager->getStore()->getName(); + } catch (NoSuchEntityException $e) { + return ''; + } + } + +} diff --git a/Controller/Social/DataDeletion.php b/Controller/Social/DataDeletion.php index 9a56bc6..bba8bfe 100644 --- a/Controller/Social/DataDeletion.php +++ b/Controller/Social/DataDeletion.php @@ -21,6 +21,7 @@ namespace Mageplaza\SocialLogin\Controller\Social; +use Exception; use Magento\Customer\Api\AccountManagementInterface; use Magento\Customer\Model\Account\Redirect as AccountRedirect; use Magento\Customer\Model\Customer; @@ -29,8 +30,9 @@ use Magento\Framework\App\ResponseInterface; use Magento\Framework\Controller\Result\RawFactory; use Magento\Framework\Controller\ResultInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\View\Result\PageFactory; use Magento\Store\Model\StoreManagerInterface; -use Mageplaza\Core\Helper\AbstractData; use Mageplaza\SocialLogin\Helper\Social as SocialHelper; use Mageplaza\SocialLogin\Model\Social; @@ -40,11 +42,30 @@ */ class DataDeletion extends AbstractSocial { + + /** + * @type PageFactory + */ + protected $resultPageFactory; + /** - * @type \Mageplaza\SocialLogin\Helper\Social + * @type SocialHelper */ protected $apiHelper; + /** + * DataDeletion constructor. + * + * @param Context $context + * @param StoreManagerInterface $storeManager + * @param AccountManagementInterface $accountManager + * @param SocialHelper $apiHelper + * @param Social $apiObject + * @param Session $customerSession + * @param AccountRedirect $accountRedirect + * @param RawFactory $resultRawFactory + * @param Customer $customerModel + */ public function __construct( Context $context, StoreManagerInterface $storeManager, @@ -54,7 +75,8 @@ public function __construct( Session $customerSession, AccountRedirect $accountRedirect, RawFactory $resultRawFactory, - Customer $customerModel + Customer $customerModel, + PageFactory $resultPageFactory ) { parent::__construct( $context, @@ -67,40 +89,50 @@ public function __construct( $resultRawFactory, $customerModel ); - + $this->resultPageFactory = $resultPageFactory; } /** - * @return ResponseInterface|ResultInterface - * @throws \Magento\Framework\Exception\NoSuchEntityException - * @throws \Zend_Log_Exception + * @return ResponseInterface|ResultInterface|void + * @throws NoSuchEntityException */ public function execute() { $param = $this->getRequest()->getParams(); - if (isset($param['type']) && $param['type'] === 'facebook') { + $resultRedirect = $this->resultRedirectFactory->create(); + + if (isset($param['type']) && $param['type'] === 'facebook' && isset($param['signed_request'])) { $signed_request = $param['signed_request']; $data = $this->parseSignedRequest($signed_request); if ($data && $data['user_id']) { $this->apiObject->load($data['user_id'], 'social_id'); try { $this->apiObject->delete(); - } catch (\Exception $e) { + } catch (Exception $e) { return $this->getResponse()->representJson(''); } } + $response = [ - 'url' => $this->getStore()->getBaseUrl() . "/sociallogin/social/datadeletion/type/facebook?id={$data['algorithm']}", - 'confirmation_code' => $data['algorithm'], + 'url' => $this->getStore()->getBaseUrl() . "sociallogin/social/datadeletion/type/facebook?id={$data['user_id']}", + 'confirmation_code' => $data['user_id'], ]; - $response = AbstractData::jsonEncode($response); + $response = json_encode($response, JSON_UNESCAPED_SLASHES); return $this->getResponse()->representJson($response); } + if (isset($param['type']) && isset($param['id'])) { + $paramsToDelete = [ + 'id' => $param['id'], + 'type' => $param['type'], + ]; + $this->_forward('index', 'index', 'cms', $paramsToDelete); - return $this->getResponse()->representJson(''); + return; + } + return $this->getResponse()->representJson(''); } /** @@ -133,4 +165,5 @@ public function base64UrlDecode($input) { return base64_decode(strtr($input, '-_', '+/')); } + } diff --git a/Plugin/CsrfValidator.php b/Plugin/CsrfValidator.php index ebb6d00..c9b4cfa 100644 --- a/Plugin/CsrfValidator.php +++ b/Plugin/CsrfValidator.php @@ -23,7 +23,6 @@ use Magento\Framework\App\ActionInterface; use Magento\Framework\App\RequestInterface; -use Mageplaza\SocialLogin\Helper\Data as HelperData; /** * Class CsrfValidation @@ -31,25 +30,14 @@ */ class CsrfValidator { - /** - * @var HelperData - */ - protected $_helperData; - - /** - * Cart constructor. - * - * @param HelperData $helperData - */ - public function __construct(HelperData $helperData) - { - $this->_helperData = $helperData; - } /** * @param \Magento\Framework\App\Request\CsrfValidator $subject + * @param callable $proceed * @param RequestInterface $request * @param ActionInterface $action + * + * @return bool */ public function aroundValidate( \Magento\Framework\App\Request\CsrfValidator $subject, @@ -61,6 +49,6 @@ public function aroundValidate( return true; } - return $proceed(); + return $proceed($request, $action); } } diff --git a/view/frontend/layout/cms_index_index.xml b/view/frontend/layout/cms_index_index.xml new file mode 100644 index 0000000..4d703c3 --- /dev/null +++ b/view/frontend/layout/cms_index_index.xml @@ -0,0 +1,31 @@ + + + + + + + + + \ No newline at end of file diff --git a/view/frontend/templates/data_deletion/delete_data.phtml b/view/frontend/templates/data_deletion/delete_data.phtml new file mode 100755 index 0000000..e57c649 --- /dev/null +++ b/view/frontend/templates/data_deletion/delete_data.phtml @@ -0,0 +1,48 @@ + +isShowConfirm()): ?> + + + From 90200617ab7cb44a9eaebe9a6d6f3302e79af54a Mon Sep 17 00:00:00 2001 From: chuccv Date: Fri, 7 Oct 2022 10:58:53 +0700 Subject: [PATCH 4/9] - ZaloProvider V3 -> V4 --- Model/Providers/Zalo.php | 49 +++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/Model/Providers/Zalo.php b/Model/Providers/Zalo.php index 0c2bcbf..3c90ecf 100644 --- a/Model/Providers/Zalo.php +++ b/Model/Providers/Zalo.php @@ -50,19 +50,21 @@ class Zalo extends Hybrid_Provider_Model_OAuth2 /** * {@inheritdoc} */ - protected $authorizeUrl = 'https://oauth.zaloapp.com/v3/permission'; + protected $authorizeUrl = 'https://oauth.zaloapp.com/v4/permission'; /** * {@inheritdoc} */ - protected $accessTokenUrl = 'https://oauth.zaloapp.com/v3/access_token'; + protected $accessTokenUrl = 'https://oauth.zaloapp.com/v4/access_token'; /** * {@inheritdoc} */ protected function getAuthorizeUrl($parameters = []) { - + $parameters = [ + 'code_challenge' => $this->generatePkceCodes(), + ]; $this->AuthorizeUrlParameters = array_merge($parameters, $this->AuthorizeUrlParameters); $this->AuthorizeUrlParameters['app_id'] = $this->AuthorizeUrlParameters['client_id']; unset($this->AuthorizeUrlParameters['client_id']); @@ -86,8 +88,9 @@ protected function exchangeCodeForAccessToken($code) $url = $this->accessTokenUrl; $params = [ 'app_id' => $this->clientId, - 'app_secret' => $this->clientSecret, - 'code' => $code + 'secret_key' => $this->clientSecret, + 'grant_type' => 'authorization_code', + 'code' => $code, ]; $urlEncodedParams = http_build_query($params, '', '&'); $url = $url . (strpos($url, '?') ? '&' : '?') . $urlEncodedParams; @@ -103,7 +106,12 @@ protected function exchangeCodeForAccessToken($code) ); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_HTTPHEADER, []); + $header = [ + "secret_key: {$this->clientSecret}", + "Content-Type: application/x-www-form-urlencoded", + ]; + curl_setopt($ch, CURLOPT_HTTPHEADER, $header); + curl_setopt($ch, CURLOPT_POST, true); $response = curl_exec($ch); curl_close($ch); @@ -158,4 +166,33 @@ public function getUserProfile() return $userProfile; } + + /** + * @param $text + * + * @return string + */ + public function base64UrlEncode($text) + { + $base64 = base64_encode($text); + $base64 = trim($base64, "="); + $base64url = strtr($base64, "+/", "-_"); + + return $base64url; + } + + /** + * @return array + */ + public function generatePkceCodes() + { + $random = bin2hex(openssl_random_pseudo_bytes(32)); + $code_verifier = $this->base64UrlEncode(pack('H*', $random)); + $code_challenge = $this->base64UrlEncode(pack('H*', hash('sha256', $code_verifier))); + + return [ + "verifier" => $code_verifier, + "challenge" => $code_challenge, + ]; + } } From a371d1c4aa87b58c864c76198535bd358f5b4a0f Mon Sep 17 00:00:00 2001 From: chuccv Date: Mon, 24 Oct 2022 08:40:36 +0700 Subject: [PATCH 5/9] - update label view status Delete data User Facebook. --- view/frontend/templates/data_deletion/delete_data.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/view/frontend/templates/data_deletion/delete_data.phtml b/view/frontend/templates/data_deletion/delete_data.phtml index e57c649..0d67e94 100755 --- a/view/frontend/templates/data_deletion/delete_data.phtml +++ b/view/frontend/templates/data_deletion/delete_data.phtml @@ -22,7 +22,7 @@ isShowConfirm()): ?>