-
Notifications
You must be signed in to change notification settings - Fork 0
Feature/secure mode #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 7 commits
4bbe230
228a32d
98abc44
8d3db1e
7520f22
8c1f1f9
63dd82e
6fd126d
e6e3ea2
7bb2744
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| <?php | ||
| /** | ||
| * Tawk.to | ||
| * | ||
| * NOTICE OF LICENSE | ||
| * | ||
| * This source file is subject to the Open Software License (OSL 3.0) | ||
| * that is bundled with this package in the file LICENSE.txt. | ||
| * It is also available through the world-wide-web at this URL: | ||
| * http://opensource.org/licenses/osl-3.0.php | ||
| * If you did not receive a copy of the license and are unable to | ||
| * obtain it through the world-wide-web, please send an email | ||
| * to support@tawk.to so we can send you a copy immediately. | ||
| * | ||
| * @copyright Copyright (c) 2024 Tawk.to | ||
| * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) | ||
| */ | ||
|
|
||
| namespace Tawk\Widget\Api; | ||
|
|
||
| interface ConfigInterface | ||
| { | ||
| const JS_API_KEY_NO_CHANGE = 'no_change'; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -21,12 +21,16 @@ | |||||||||||||||||||||||
| use Magento\Framework\View\Element\Template; | ||||||||||||||||||||||||
| use Magento\Framework\Escaper; | ||||||||||||||||||||||||
| use Magento\Customer\Model\SessionFactory; | ||||||||||||||||||||||||
| use Magento\Framework\Encryption\EncryptorInterface; | ||||||||||||||||||||||||
| use Magento\Framework\Exception\LocalizedException; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| use Tawk\Modules\UrlPatternMatcher; | ||||||||||||||||||||||||
| use Tawk\Widget\Model\WidgetFactory; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| class Embed extends Template | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| public const TAWKTO_VISITOR_SESSION = 'TAWKTO_VISITOR_SESSION'; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||
| * Tawk.to Widget Model instance | ||||||||||||||||||||||||
| * | ||||||||||||||||||||||||
|
|
@@ -76,20 +80,29 @@ class Embed extends Template | |||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
| protected $escaper; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||
| * Encryptor instance | ||||||||||||||||||||||||
| * | ||||||||||||||||||||||||
| * @var EncryptorInterface $encryptor | ||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
| protected $encryptor; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||
| * Constructor | ||||||||||||||||||||||||
| * | ||||||||||||||||||||||||
| * @param SessionFactory $sessionFactory Session Factory instance | ||||||||||||||||||||||||
| * @param WidgetFactory $modelFactory Tawk.to Widget Model instance | ||||||||||||||||||||||||
| * @param Template\Context $context Template Context | ||||||||||||||||||||||||
| * @param Escaper $escaper Escaper instance | ||||||||||||||||||||||||
| * @param EncryptorInterface $encryptor Encryptor instance | ||||||||||||||||||||||||
| * @param array $data Template data | ||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
| public function __construct( | ||||||||||||||||||||||||
| SessionFactory $sessionFactory, | ||||||||||||||||||||||||
| WidgetFactory $modelFactory, | ||||||||||||||||||||||||
| Template\Context $context, | ||||||||||||||||||||||||
| Escaper $escaper, | ||||||||||||||||||||||||
| EncryptorInterface $encryptor, | ||||||||||||||||||||||||
| array $data = [] | ||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||
| parent::__construct($context, $data); | ||||||||||||||||||||||||
|
|
@@ -100,6 +113,7 @@ public function __construct( | |||||||||||||||||||||||
| $this->request = $context->getRequest(); | ||||||||||||||||||||||||
| $this->modelSessionFactory = $sessionFactory->create(); | ||||||||||||||||||||||||
| $this->escaper = $escaper; | ||||||||||||||||||||||||
| $this->encryptor = $encryptor; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||
|
|
@@ -146,7 +160,8 @@ private function getWidgetModel() | |||||||||||||||||||||||
| * | ||||||||||||||||||||||||
| * @return array { | ||||||||||||||||||||||||
| * name: string, | ||||||||||||||||||||||||
| * email: string | ||||||||||||||||||||||||
| * email: string, | ||||||||||||||||||||||||
| * hash: string | ||||||||||||||||||||||||
| * } | ||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
| public function getCurrentCustomerDetails() | ||||||||||||||||||||||||
|
|
@@ -160,12 +175,71 @@ public function getCurrentCustomerDetails() | |||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| $customerSession = $this->modelSessionFactory->getCustomer(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| $hash = $this->getVisitorHash($customerSession->getEmail()); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| return [ | ||||||||||||||||||||||||
| 'name' => $customerSession->getName(), | ||||||||||||||||||||||||
| 'email' => $customerSession->getEmail() | ||||||||||||||||||||||||
| 'email' => $customerSession->getEmail(), | ||||||||||||||||||||||||
| 'hash' => $hash | ||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||
| * Get visitor hash | ||||||||||||||||||||||||
| * | ||||||||||||||||||||||||
| * @param string $email Visitor email | ||||||||||||||||||||||||
| * @return string | ||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
| private function getVisitorHash(string $email) | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| $configVersion = $this->model->getConfigVersion(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if ($this->modelSessionFactory->hasData(self::TAWKTO_VISITOR_SESSION)) { | ||||||||||||||||||||||||
| $currentSession = $this->modelSessionFactory->getData(self::TAWKTO_VISITOR_SESSION); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if (isset($currentSession['hash']) && | ||||||||||||||||||||||||
| $currentSession['email'] === $email && | ||||||||||||||||||||||||
| $currentSession['config_version'] === $configVersion) { | ||||||||||||||||||||||||
| return $currentSession['hash']; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||
| $jsApiKey = $this->decryptJsApiKey($this->model->getJsApiKey()); | ||||||||||||||||||||||||
| } catch (LocalizedException $e) { | ||||||||||||||||||||||||
| return ''; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| $hash = hash_hmac('sha256', $email, $jsApiKey); | ||||||||||||||||||||||||
|
Comment on lines
+219
to
+221
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Additional error handling needed for decryption. The decrypt operation could fail and throw an exception. Consider adding specific error handling for the decryption operation. - $jsApiKey = $this->encryptor->decrypt($encryptedJsApiKey);
+ try {
+ $jsApiKey = $this->encryptor->decrypt($encryptedJsApiKey);
+ } catch (\Exception $e) {
+ $this->logger->error('Failed to decrypt JS API key: ' . $e->getMessage());
+ return null;
+ }📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| $this->modelSessionFactory->setData(self::TAWKTO_VISITOR_SESSION, [ | ||||||||||||||||||||||||
| 'hash' => $hash, | ||||||||||||||||||||||||
| 'email' => $email, | ||||||||||||||||||||||||
| 'config_version' => $configVersion, | ||||||||||||||||||||||||
| ]); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| return $hash; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||
| * Retrieve JS API key | ||||||||||||||||||||||||
| * | ||||||||||||||||||||||||
| * @param string $js_api_key Encrypted JS API key | ||||||||||||||||||||||||
| * @return string | ||||||||||||||||||||||||
| * @throws \Exception error retrieving JS API key | ||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
| private function decryptJsApiKey(string $js_api_key) | ||||||||||||||||||||||||
| { | ||||||||||||||||||||||||
| if (empty($js_api_key)) { | ||||||||||||||||||||||||
| throw new LocalizedException(__('JS API key is empty')); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| $key = $this->encryptor->decrypt($js_api_key); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| return $key; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||
| * To or to not display the selected widget. | ||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| #!/bin/sh | ||
|
|
||
|
Comment on lines
+1
to
+2
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Proper Shebang & Error Handling Consideration The script begins with a proper shebang ( |
||
| composer run clean | ||
|
|
||
| mkdir -p ./tmp/tawkmagento2 | ||
| cp -r ./view ./tmp/tawkmagento2 | ||
| cp -r ./etc ./tmp/tawkmagento2 | ||
| cp -r ./Setup ./tmp/tawkmagento2 | ||
| cp -r ./Model ./tmp/tawkmagento2 | ||
| cp -r ./Controller ./tmp/tawkmagento2 | ||
| cp -r ./Block ./tmp/tawkmagento2 | ||
| cp -r ./Helper ./tmp/tawkmagento2 | ||
| cp -r ./Api ./tmp/tawkmagento2 | ||
| cp ./registration.php ./tmp/tawkmagento2 | ||
| cp ./composer.json ./tmp/tawkmagento2 | ||
| cp README.md ./tmp/tawkmagento2 | ||
|
|
||
| (cd ./tmp && zip -9 -rq ./tawkmagento2.zip ./tawkmagento2) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check if you even have a key before attempting to de-crypt