download all files

This commit is contained in:
Roman Pyrih
2025-06-24 14:14:35 +02:00
parent ebed09c00b
commit 4c71b5d9c2
72007 changed files with 10407727 additions and 40029 deletions

View File

@@ -0,0 +1,243 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsAccounts\Repository;
use Exception;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Token;
use Lcobucci\JWT\Token\InvalidTokenStructure;
use Module;
use PrestaShop\Module\PsAccounts\Exception\RefreshTokenException;
use PrestaShop\Module\PsAccounts\Log\Logger;
use PrestaShop\Module\PsAccounts\Service\ShopLinkAccountService;
use Ps_accounts;
/**
* Class AbstractTokenRepository
*/
abstract class AbstractTokenRepository
{
const MAX_TRIES_BEFORE_CLEAN_CREDENTIALS_ON_REFRESH_TOKEN_FAILURE = 3;
const TOKEN_TYPE = '';
const TOKEN_KEY = '';
/**
* @var ConfigurationRepository
*/
protected $configuration;
/**
* @var string
*/
protected $tokenType;
/**
* AbstractTokenRepository constructor.
*
* @param ConfigurationRepository $configuration
*/
public function __construct(
ConfigurationRepository $configuration
) {
$this->configuration = $configuration;
}
/**
* @return TokenClientInterface
*
* @throws Exception
*/
abstract protected function client();
/**
* @return Token|null
*/
abstract public function getToken();
/**
* @return string
*/
abstract public function getTokenUuid();
/**
* @return string
*/
abstract public function getRefreshToken();
/**
* @return void
*/
abstract public function cleanupCredentials();
/**
* @param string $idToken
* @param string $refreshToken
*
* @return void
*/
abstract public function updateCredentials($idToken, $refreshToken);
/**
* @param bool $forceRefresh
*
* @return Token|null
*
* @throws \Throwable
*/
public function getOrRefreshToken($forceRefresh = false)
{
if (true === $forceRefresh || $this->isTokenExpired()) {
$refreshToken = $this->getRefreshToken();
if (is_string($refreshToken) && '' != $refreshToken) {
try {
$token = $this->refreshToken($refreshToken);
$this->updateCredentials(
(string) $token,
$refreshToken
);
} catch (RefreshTokenException $e) {
Logger::getInstance()->debug($e);
}
}
}
return $this->getToken();
}
/**
* @return bool
*
* @throws Exception
*/
public function isTokenExpired()
{
$token = $this->getToken();
return $token ? $token->isExpired(new \DateTime()) : true;
}
/**
* @param string $token
*
* @return Token|null
*/
public function parseToken($token)
{
try {
return (new Parser())->parse((string) $token);
} catch (InvalidTokenStructure $e) {
return null;
}
}
/**
* @param string $refreshToken
*
* @return Token|null idToken
*
* @throws RefreshTokenException
* @throws Exception
*/
public function refreshToken($refreshToken)
{
$response = $this->client()->refreshToken($refreshToken);
if ($response && true === $response['status']) {
$token = $this->parseToken($response['body'][static::TOKEN_KEY]);
$this->onRefreshTokenSuccess();
return $token;
}
if ($response['httpCode'] >= 400 && $response['httpCode'] < 500) {
$this->onRefreshTokenFailure();
}
$errorMsg = isset($response['body']['message']) ? $response['body']['message'] : '';
throw new RefreshTokenException('Unable to refresh ' . static::TOKEN_TYPE . ' token : ' . $response['httpCode'] . ' ' . print_r($errorMsg, true));
}
/**
* @param string $idToken
* @param string $refreshToken
*
* @return Token|null verified or refreshed token on success
*
* @throws RefreshTokenException
* @throws Exception
*/
public function verifyToken($idToken, $refreshToken)
{
$response = $this->client()->verifyToken($idToken);
if ($response && true === $response['status']) {
return $this->parseToken($idToken);
}
return $this->refreshToken($refreshToken);
}
/**
* @return void
*/
protected function onRefreshTokenFailure()
{
$attempt = $this->configuration->getRefreshTokenFailure(static::TOKEN_TYPE);
if ($attempt >= (static::MAX_TRIES_BEFORE_CLEAN_CREDENTIALS_ON_REFRESH_TOKEN_FAILURE - 1)) {
$this->onMaxRefreshTokenAttempts();
$this->configuration->updateRefreshTokenFailure(static::TOKEN_TYPE, 0);
return;
}
$this->configuration->updateRefreshTokenFailure(
static::TOKEN_TYPE,
++$attempt
);
}
/**
* @return void
*/
protected function onRefreshTokenSuccess()
{
$this->configuration->updateRefreshTokenFailure(static::TOKEN_TYPE, 0);
}
/**
* @return void
*
* @throws Exception
*/
protected function onMaxRefreshTokenAttempts()
{
/** @var Ps_accounts $module */
$module = Module::getInstanceByName('ps_accounts');
/** @var ShopLinkAccountService $service */
$service = $module->getService(ShopLinkAccountService::class);
$service->resetLinkAccount();
}
}

View File

@@ -0,0 +1,385 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsAccounts\Repository;
use PrestaShop\Module\PsAccounts\Adapter\Configuration;
class ConfigurationRepository
{
/**
* @var Configuration
*/
private $configuration;
/**
* ConfigurationRepository constructor.
*
* @param Configuration|null $configuration
*/
public function __construct(Configuration $configuration = null)
{
$this->configuration = $configuration;
}
/**
* @return int
*/
public function getShopId()
{
return $this->configuration->getIdShop();
}
/**
* @param int $shopId
*
* @return void
*/
public function setShopId($shopId)
{
$this->configuration->setIdShop($shopId);
}
/**
* @return string
*/
public function getFirebaseIdToken()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_ID_TOKEN);
}
/**
* @return string
*/
public function getFirebaseRefreshToken()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN);
}
/**
* @param string $idToken
* @param string $refreshToken
*
* @return void
*/
public function updateFirebaseIdAndRefreshTokens($idToken, $refreshToken)
{
if (false === $this->configuration->get(Configuration::PS_PSX_FIREBASE_ID_TOKEN)) {
// FIXME: This to avoid mutual disconnect between ps_accounts & ps_checkout
$this->configuration->set(Configuration::PS_PSX_FIREBASE_ID_TOKEN, $idToken);
$this->configuration->set(Configuration::PS_PSX_FIREBASE_REFRESH_TOKEN, $refreshToken);
$this->configuration->set(Configuration::PS_PSX_FIREBASE_REFRESH_DATE, date('Y-m-d H:i:s'));
}
$this->configuration->set(Configuration::PS_ACCOUNTS_FIREBASE_ID_TOKEN, $idToken);
$this->configuration->set(Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN, $refreshToken);
}
/**
* Check if we have a refresh token.
*
* @return bool
*/
public function hasFirebaseRefreshToken()
{
return !empty($this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN));
}
/**
* @return string|null
*/
public function getFirebaseEmail()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_EMAIL);
}
/**
* @param string $email
*
* @return void
*/
public function updateFirebaseEmail($email)
{
if (false === $this->configuration->get(Configuration::PS_PSX_FIREBASE_EMAIL)) {
$this->configuration->set(Configuration::PS_PSX_FIREBASE_EMAIL, $email);
}
$this->configuration->set(Configuration::PS_ACCOUNTS_FIREBASE_EMAIL, $email);
}
/**
* @return string|null
*/
public function getEmployeeId()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_EMPLOYEE_ID);
}
/**
* @param string $employeeId
*
* @return void
*/
public function updateEmployeeId($employeeId)
{
$this->configuration->set(Configuration::PS_ACCOUNTS_EMPLOYEE_ID, $employeeId);
}
/**
* @return bool
*/
public function firebaseEmailIsVerified()
{
return in_array(
$this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_EMAIL_IS_VERIFIED),
['1', 1, true]
);
}
/**
* @param bool $status
*
* @return void
*/
public function updateFirebaseEmailIsVerified($status)
{
$this->configuration->set(
Configuration::PS_ACCOUNTS_FIREBASE_EMAIL_IS_VERIFIED,
(string) $status
);
}
/**
* @return string
*/
public function getShopUuid()
{
return $this->configuration->get(Configuration::PSX_UUID_V4);
}
/**
* @param string $uuid Firebase User UUID
*
* @return void
*/
public function updateShopUuid($uuid)
{
if (false === $this->configuration->get(Configuration::PS_CHECKOUT_SHOP_UUID_V4)) {
$this->configuration->set(Configuration::PS_CHECKOUT_SHOP_UUID_V4, $uuid);
}
$this->configuration->set(Configuration::PSX_UUID_V4, $uuid);
}
/**
* @return string
*/
public function getAccountsRsaPrivateKey()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_RSA_PRIVATE_KEY);
}
/**
* @param string $key
*
* @return void
*/
public function updateAccountsRsaPrivateKey($key)
{
$this->configuration->set(Configuration::PS_ACCOUNTS_RSA_PRIVATE_KEY, $key);
}
/**
* @return string|bool
*/
public function getAccountsRsaPublicKey()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_RSA_PUBLIC_KEY);
}
/**
* @param string $key
*
* @return void
*/
public function updateAccountsRsaPublicKey($key)
{
$this->configuration->set(Configuration::PS_ACCOUNTS_RSA_PUBLIC_KEY, $key);
}
/**
* @return string
*/
public function getAccountsRsaSignData()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_RSA_SIGN_DATA);
}
/**
* @param string $signData
*
* @return void
*/
public function updateAccountsRsaSignData($signData)
{
$this->configuration->set(Configuration::PS_ACCOUNTS_RSA_SIGN_DATA, $signData);
}
/**
* @return bool
*/
public function sslEnabled()
{
return true == $this->configuration->get('PS_SSL_ENABLED')
|| true == $this->configuration->get('PS_SSL_ENABLED_EVERYWHERE');
}
/**
* @return mixed
*/
public function getUserFirebaseUuid()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_USER_FIREBASE_UUID);
}
/**
* @param string $uuid
*
* @return void
*/
public function updateUserFirebaseUuid($uuid)
{
$this->configuration->set(Configuration::PS_ACCOUNTS_USER_FIREBASE_UUID, $uuid);
}
/**
* @return mixed
*/
public function getUserFirebaseIdToken()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_USER_FIREBASE_ID_TOKEN);
}
/**
* @param string $idToken
*
* @return void
*/
public function updateUserFirebaseIdToken($idToken)
{
$this->configuration->set(Configuration::PS_ACCOUNTS_USER_FIREBASE_ID_TOKEN, $idToken);
}
/**
* @return mixed
*/
public function getUserFirebaseRefreshToken()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_USER_FIREBASE_REFRESH_TOKEN);
}
/**
* @param string $refreshToken
*
* @return void
*/
public function updateUserFirebaseRefreshToken($refreshToken)
{
$this->configuration->set(Configuration::PS_ACCOUNTS_USER_FIREBASE_REFRESH_TOKEN, $refreshToken);
}
/**
* Get shop who is defined as main in the prestashop
*
* @return \Shop
*/
public function getMainShop()
{
$mainShopId = \Db::getInstance()->getValue('SELECT value FROM ' . _DB_PREFIX_ . "configuration WHERE name = 'PS_SHOP_DEFAULT'");
$shop = new \Shop((int) $mainShopId);
return $shop;
}
/**
* specify id_shop & id_shop_group for shop
*
* @return void
*/
public function migrateToMultiShop()
{
$shop = $this->getMainShop();
\Db::getInstance()->query(
'UPDATE ' . _DB_PREFIX_ . 'configuration SET id_shop = ' . (int) $shop->id . ', id_shop_group = ' . (int) $shop->id_shop_group .
" WHERE (name like 'PS_ACCOUNTS_%' OR name = 'PSX_UUID_V4')" .
' AND id_shop IS NULL AND id_shop_group IS NULL;'
);
}
/**
* nullify id_shop & id_shop_group for shop
*
* @return void
*/
public function migrateToSingleShop()
{
$shop = $this->getMainShop();
\Db::getInstance()->query(
'UPDATE ' . _DB_PREFIX_ . 'configuration SET id_shop = NULL, id_shop_group = NULL' .
" WHERE (name like 'PS_ACCOUNTS_%' OR name = 'PSX_UUID_V4')" .
' AND id_shop = ' . (int) $shop->id . ';'
);
}
/**
* @param string $type
*
* @return int
*/
public function getRefreshTokenFailure($type)
{
if ($type === 'shop') {
return (int) $this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN_FAILURE, '0');
}
if ($type === 'user') {
return (int) $this->configuration->get(Configuration::PS_ACCOUNTS_USER_FIREBASE_REFRESH_TOKEN_FAILURE, '0');
}
return 0;
}
/**
* @param string $type
* @param int $attempt
*
* @return void
*/
public function updateRefreshTokenFailure($type, $attempt)
{
switch ($type) {
case 'shop':
$this->configuration->set(Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN_FAILURE, (string) $attempt);
break;
case 'user':
$this->configuration->set(Configuration::PS_ACCOUNTS_USER_FIREBASE_REFRESH_TOKEN_FAILURE, (string) $attempt);
break;
default:
break;
}
}
}

View File

@@ -0,0 +1,94 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsAccounts\Repository;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Token;
use PrestaShop\Module\PsAccounts\Api\Client\AccountsClient;
/**
* Class ShopTokenRepository
*/
class ShopTokenRepository extends AbstractTokenRepository
{
const TOKEN_TYPE = 'shop';
const TOKEN_KEY = 'token';
/**
* @return AccountsClient
*
* @throws \Exception
*/
protected function client()
{
/** @var \Ps_accounts $module */
$module = \Module::getInstanceByName('ps_accounts');
return $module->getService(AccountsClient::class);
}
/**
* @return Token|null
*/
public function getToken()
{
return $this->parseToken($this->configuration->getFirebaseIdToken());
}
/**
* @return string
*/
public function getTokenUuid()
{
return $this->configuration->getShopUuid();
}
/**
* @return string
*/
public function getRefreshToken()
{
return $this->configuration->getFirebaseRefreshToken();
}
/**
* @return void
*/
public function cleanupCredentials()
{
$this->configuration->updateShopUuid('');
$this->configuration->updateFirebaseIdAndRefreshTokens('', '');
}
/**
* @param string $idToken
* @param string $refreshToken
*
* @return void
*/
public function updateCredentials($idToken, $refreshToken)
{
$token = (new Parser())->parse((string) $idToken);
$this->configuration->updateShopUuid($token->getClaim('user_id'));
$this->configuration->updateFirebaseIdAndRefreshTokens((string) $idToken, (string) $refreshToken);
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsAccounts\Repository;
interface TokenClientInterface
{
/**
* @param string $refreshToken
*
* @return array response
*/
public function refreshToken($refreshToken);
/**
* @param string $idToken
*
* @return array response
*/
public function verifyToken($idToken);
}

View File

@@ -0,0 +1,130 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsAccounts\Repository;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Token;
use PrestaShop\Module\PsAccounts\Api\Client\SsoClient;
use PrestaShop\Module\PsAccounts\Exception\RefreshTokenException;
/**
* Class UserTokenRepository
*/
class UserTokenRepository extends AbstractTokenRepository
{
const TOKEN_TYPE = 'user';
const TOKEN_KEY = 'idToken';
/**
* @return SsoClient
*
* @throws \Exception
*/
protected function client()
{
/** @var \Ps_accounts $module */
$module = \Module::getInstanceByName('ps_accounts');
return $module->getService(SsoClient::class);
}
/**
* @return Token|null
*/
public function getToken()
{
return $this->parseToken($this->configuration->getUserFirebaseIdToken());
}
/**
* @return string
*/
public function getTokenUuid()
{
return $this->configuration->getUserFirebaseUuid();
}
/**
* @return string
*/
public function getRefreshToken()
{
return $this->configuration->getUserFirebaseRefreshToken();
}
/**
* @return void
*/
public function cleanupCredentials()
{
$this->configuration->updateUserFirebaseUuid('');
$this->configuration->updateUserFirebaseIdToken('');
$this->configuration->updateUserFirebaseRefreshToken('');
$this->configuration->updateFirebaseEmail('');
//$this->configuration->updateFirebaseEmailIsVerified(false);
}
/**
* @param string $idToken
* @param string $refreshToken
*
* @return void
*/
public function updateCredentials($idToken, $refreshToken)
{
$token = (new Parser())->parse((string) $idToken);
$uuid = $token->claims()->get('user_id');
$this->configuration->updateUserFirebaseUuid($uuid);
$this->configuration->updateUserFirebaseIdToken($idToken);
$this->configuration->updateUserFirebaseRefreshToken($refreshToken);
$this->configuration->updateFirebaseEmail($token->claims()->get('email'));
}
/**
* @return string
*/
public function getTokenEmail()
{
return $this->configuration->getFirebaseEmail();
}
/**
* @return bool
*
* @throws \Exception
*/
public function getTokenEmailVerified()
{
$token = $this->getToken();
// FIXME : just query sso api and don't refresh token everytime
if (null !== $token && !$token->claims()->get('email_verified')) {
try {
$token = $this->getOrRefreshToken(true);
} catch (RefreshTokenException $e) {
}
}
return null !== $token && (bool) $token->claims()->get('email_verified');
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;