Subida del módulo y tema de PrestaShop

This commit is contained in:
Kaloyan
2026-04-09 18:31:51 +02:00
parent 12c253296f
commit 16b3ff9424
39262 changed files with 7418797 additions and 0 deletions

View File

@@ -0,0 +1,368 @@
<?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
*/
require_once __DIR__ . '/../../src/Polyfill/Traits/Controller/AjaxRender.php';
use PrestaShop\Module\PsAccounts\Account\Exception\UnknownStatusException;
use PrestaShop\Module\PsAccounts\Account\Session\Firebase\ShopSession;
use PrestaShop\Module\PsAccounts\Account\ShopUrl;
use PrestaShop\Module\PsAccounts\Account\StatusManager;
use PrestaShop\Module\PsAccounts\AccountLogin\OAuth2Session;
use PrestaShop\Module\PsAccounts\Adapter\Link as AccountsLink;
use PrestaShop\Module\PsAccounts\Installer\Installer;
use PrestaShop\Module\PsAccounts\Log\Logger;
use PrestaShop\Module\PsAccounts\Polyfill\Traits\Controller\AjaxRender;
use PrestaShop\Module\PsAccounts\Provider\ShopProvider;
use PrestaShop\Module\PsAccounts\Service\SentryService;
use PrestaShop\Module\PsAccounts\Service\UpgradeService;
/**
* Controller for all ajax calls.
*/
class AdminAjaxPsAccountsController extends \ModuleAdminController
{
use AjaxRender;
/**
* @var Ps_accounts
*/
public $module;
/**
* @var string
*/
private $alertCss = '
<style>
.acc-flex
{
display: flex !important;
}
.acc-btn
{
display: inline-block !important;
text-align: center !important;
vertical-align: middle !important;
user-select: none !important;
border: 1px solid transparent !important;
padding: .5rem 1rem !important;
font-size: .875rem !important;
line-height: 1.5 !important;
font-weight: 600 !important;
border-width: 1px !important;
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out !important;
cursor: pointer !important;
}
.acc-btn-warning
{
width: max-content !important;
color: #1d1d1b !important;
background-color: #FFF5E5 !important;
border-color: #ffb000 !important;
}
.acc-btn-warning:hover
{
background-color: #ffeccc !important;
}
.acc-btn-warning:focus, .acc-btn-warning.focus
{
background-color: #ffeccc !important;
}
.acc-btn-danger
{
width: max-content !important;
color: #1d1d1b !important;
background-color: #ffe4e6 !important;
border-color: #ba151a !important;
}
.acc-btn-danger:hover
{
background-color: #fdbfbf !important;
}
.acc-btn-danger:focus, .acc-btn-danger.focus
{
background-color: #fdbfbf !important;
}
@media(max-width: 768px)
{
.acc-flex {
flex-direction: column !important;
}
.acc-btn-warning,
.acc-btn-danger
{
margin-top: 1em !important;
}
}
.acc-flex-grow-1
{
-webkit-box-flex: 1 !important;
-ms-flex-positive: 1 !important;
flex-grow: 1 !important;
}
.acc-alert-title
{
font-weight: bold !important;
margin-bottom: .9375rem !important;
}
.acc-list
{
list-style-type: none;
padding-left: 0 !important;
}
.acc-alert
{
}
.acc-alert-warning
{
background-color: #FFF5E5 !important;
position: relative !important;
padding: 16px 15px 16px 56px !important;
font-size: 14px !important;
border: solid 1px #ffb000 !important;
color: #1d1d1b !important;
}
.acc-alert-danger
{
background-color: #ffe4e6 !important;
position: relative !important;
padding: 16px 15px 16px 56px !important;
font-size: 14px !important;
border: solid 1px #ba151a !important;
color: #1d1d1b !important;
}
</style>
';
/**
* @var string
*/
private $translationClass;
/**
* AdminAjaxPsAccountsController constructor.
*
* @throws Exception
*/
public function __construct()
{
parent::__construct();
$this->ajax = true;
$this->content_only = true;
$this->translationClass = self::class;
}
/**
* @return void
*
* @throws Exception
*/
public function ajaxProcessGetOrRefreshToken()
{
try {
/** @var ShopSession $shopSession */
$shopSession = $this->module->getService(ShopSession::class);
header('Content-Type: text/json');
$token = $shopSession->getValidToken();
$this->ajaxRender(
(string) json_encode([
'token' => (string) $token->getJwt(),
'refreshToken' => $token->getRefreshToken(),
])
);
} catch (Exception $e) {
SentryService::captureAndRethrow($e);
}
}
/**
* @return void
*
* @throws Exception
*/
public function ajaxProcessGetOrRefreshAccessToken()
{
try {
/** @var OAuth2Session $oauth2Session */
$oauth2Session = $this->module->getService(OAuth2Session::class);
header('Content-Type: text/json');
$this->ajaxRender(
(string) json_encode([
'token' => (string) $oauth2Session->getOrRefreshAccessToken(),
])
);
} catch (Exception $e) {
SentryService::captureAndRethrow($e);
}
}
/**
* @return void
*/
public function ajaxProcessGetNotifications()
{
$notifications = [];
try {
$notifications = array_merge(
$this->getNotificationsUpgradeFailed(),
$this->getNotificationsUrlMismatch()
);
} catch (\Exception $e) {
Logger::getInstance()->error($e->getMessage());
} catch (\Throwable $e) {
Logger::getInstance()->error($e->getMessage());
}
$this->ajaxRender(
(string) json_encode($notifications ?: [])
);
}
/**
* @return array|array[]
*
* @throws UnknownStatusException
*/
protected function getNotificationsUrlMismatch()
{
/** @var StatusManager $statusManager */
$statusManager = $this->module->getService(StatusManager::class);
if (!$statusManager->identityCreated()) {
return [];
}
$status = $statusManager->getStatus();
$shopId = $this->context->shop->id;
$cloudShopUrl = ShopUrl::createFromStatus($status, $shopId)->trimmed();
/** @var ShopProvider $shopProvider */
$shopProvider = $this->module->getService(ShopProvider::class);
$localShopUrl = $shopProvider->getUrl($shopId)->trimmed();
try {
if ($cloudShopUrl->frontendUrlEquals($localShopUrl)) {
return [];
}
} catch (\InvalidArgumentException $e) {
Logger::getInstance()->error($e->getMessage());
return [];
}
/** @var AccountsLink $link */
$link = $this->module->getService(AccountsLink::class);
$moduleLink = $link->getAdminLink('AdminModules', true, [], [
'configure' => 'ps_accounts',
]);
return [[
'html' => $this->alertCss . '
<div class="alert alert-warning acc-alert acc-alert-warning acc-flex">
<div class="acc-flex-grow-1">
<div class="acc-alert-title">
' . $this->module->l('Action required: confirm your store URL', $this->translationClass) . '
</div>
<p>
' . $this->module->l('We\'ve noticed that your store\'s URL no longer matches the one registered in your PrestaShop Account.', $this->translationClass) . '
<br>
' . $this->module->l('For your services to function properly, you must either confirm this change or create a new identity for your store.', $this->translationClass) . '
</p>
<ul class="acc-list">
<li>- ' . $this->module->l('Current store URL', $this->translationClass) . ': <em>' . $localShopUrl->getFrontendUrl() . '</em></li>
<li>- ' . $this->module->l('URL registered in PrestaShop Account', $this->translationClass) . ': <em>' . $cloudShopUrl->getFrontendUrl() . '</em></li>
</ul>
</div>
<div>
<button class="btn warning btn-outline-warning acc-btn btn-warning acc-btn-warning" onclick="document.location=\'' . $moduleLink . '\'">
' . $this->module->l('Review settings', $this->translationClass) . '
</button>
</div>
</div>
',
]];
}
/**
* @return array|array[]
*/
protected function getNotificationsUpgradeFailed()
{
/** @var StatusManager $statusManager */
$statusManager = $this->module->getService(StatusManager::class);
/** @var UpgradeService $upgradeService */
$upgradeService = $this->module->getService(UpgradeService::class);
if ($upgradeService->getCoreRegisteredVersion() === \Ps_accounts::VERSION &&
(!$statusManager->identityCreated() || $upgradeService->getRegisteredVersion() === \Ps_accounts::VERSION)) {
return [];
}
/** @var AccountsLink $link */
$link = $this->module->getService(AccountsLink::class);
$resetLink = $link->getAdminLink('AdminAjaxPsAccounts', true, [], ['ajax' => 1, 'action' => 'resetModule']);
return [[
'html' => $this->alertCss . '
<div class="alert alert-danger acc-alert acc-alert-danger acc-flex">
<div class="acc-flex-grow-1">
<div class="acc-alert-title">
' . $this->module->l('Action required: reset your PS Account module', $this->translationClass) . '
</div>
<p>' . $this->module->l('A simple reset is needed to finish the update and ensure all your modules are working correctly.', $this->translationClass) . '</p>
</div>
<div>
<button class="btn danger btn-outline-danger acc-btn btn-danger acc-btn-danger"
onclick="this.disabled = true; this.innerHTML = \'' . $this->module->l('Resetting module...', $this->translationClass) . '\'; fetch(\'' . $resetLink . '\').then(response => {document.location.reload();})">
' . $this->module->l('Reset module', $this->translationClass) . '
</button>
</div>
</div>
',
]];
}
/**
* @return void
*/
public function ajaxProcessResetModule()
{
$status = false;
try {
/** @var Installer $installer */
$installer = $this->module->getService(Installer::class);
$status = $installer->resetModule('ps_accounts');
} catch (\Exception $e) {
Logger::getInstance()->error($e->getMessage());
} catch (\Throwable $e) {
Logger::getInstance()->error($e->getMessage());
}
$this->ajaxRender(
(string) json_encode([
'status' => $status,
])
);
}
}

View File

@@ -0,0 +1,241 @@
<?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
*/
require_once __DIR__ . '/../../src/Http/Controller/AbstractAdminAjaxCorsController.php';
use PrestaShop\Module\PsAccounts\Account\Command\CreateIdentityCommand;
use PrestaShop\Module\PsAccounts\Account\Command\MigrateOrCreateIdentityV8Command;
use PrestaShop\Module\PsAccounts\Account\Command\VerifyIdentityCommand;
use PrestaShop\Module\PsAccounts\Account\Exception\RefreshTokenException;
use PrestaShop\Module\PsAccounts\Account\Query\GetContextQuery;
use PrestaShop\Module\PsAccounts\Account\StatusManager;
use PrestaShop\Module\PsAccounts\Context\ShopContext;
use PrestaShop\Module\PsAccounts\Cqrs\CommandBus;
use PrestaShop\Module\PsAccounts\Cqrs\QueryBus;
use PrestaShop\Module\PsAccounts\Http\Controller\AbstractAdminAjaxCorsController;
use PrestaShop\Module\PsAccounts\Log\Logger;
use PrestaShop\Module\PsAccounts\Service\Accounts;
use PrestaShop\Module\PsAccounts\Service\Accounts\AccountsException;
use PrestaShop\Module\PsAccounts\Service\Accounts\AccountsService;
use PrestaShop\Module\PsAccounts\Service\OAuth2;
/**
* Controller for all ajax calls.
*/
class AdminAjaxV2PsAccountsController extends AbstractAdminAjaxCorsController
{
/**
* @var CommandBus
*/
private $commandBus;
/**
* @var QueryBus
*/
private $queryBus;
/**
* @var ShopContext
*/
private $shopContext;
/**
* AdminAjaxV2PsAccountsController constructor.
*
* @throws Exception
*/
public function __construct()
{
parent::__construct();
$this->commandBus = $this->module->getService(CommandBus::class);
$this->queryBus = $this->module->getService(QueryBus::class);
$this->shopContext = $this->module->getService(ShopContext::class);
}
/**
* @return void
*
* @throws Exception
*/
public function ajaxProcessGetContext()
{
$command = new GetContextQuery(
Tools::getValue('source', 'ps_accounts'),
Tools::getValue('context_type', null),
Tools::getValue('context_id', null),
filter_var(Tools::getValue('refresh', false), FILTER_VALIDATE_BOOLEAN)
);
$this->ajaxRender(
(string) json_encode($this->queryBus->handle($command))
);
}
/**
* @return void
*
* @throws Exception
*/
public function ajaxProcessFallbackCreateIdentity()
{
$shopId = Tools::getValue('shop_id', null);
$source = Tools::getValue('source', 'ps_accounts');
if (!$shopId) {
throw new Exception('Shop ID is required for migration or creation.');
}
$this->shopContext->execInShopContext($shopId, function () use ($shopId, $source) {
/** @var StatusManager $statusManager */
$statusManager = $this->module->getService(StatusManager::class);
$statusManager->withThrowException(true);
$command = (new MigrateOrCreateIdentityV8Command($shopId))
->withOrigin(AccountsService::ORIGIN_FALLBACK)
->withSource($source);
$this->commandBus->handle($command);
$statusManager->resetThrowException();
});
$this->ajaxRender(
(string) json_encode([
'success' => true,
])
);
}
/**
* @return void
*
* @throws Exception
*/
public function ajaxProcessRenewIdentity()
{
$shopId = Tools::getValue('shop_id', null);
$source = Tools::getValue('source', 'ps_accounts');
if (!$shopId) {
throw new Exception('Shop ID is required for renew.');
}
$this->shopContext->execInShopContext($shopId, function () use ($shopId, $source) {
$command = (new CreateIdentityCommand($shopId, true))
->withOrigin(AccountsService::ORIGIN_MISMATCH_CREATE)
->withSource($source);
$this->commandBus->handle($command);
});
$this->ajaxRender(
(string) json_encode([
'success' => true,
])
);
}
/**
* @return void
*
* @throws Exception
*/
public function ajaxProcessUpdateIdentity()
{
$shopId = Tools::getValue('shop_id', null);
$source = Tools::getValue('source', 'ps_accounts');
if (!$shopId) {
throw new Exception('Shop ID is required for update.');
}
$this->shopContext->execInShopContext($shopId, function () use ($shopId, $source) {
$command = (new VerifyIdentityCommand($shopId, true))
->withOrigin(AccountsService::ORIGIN_MISMATCH_UPDATE)
->withSource($source);
$this->commandBus->handle($command);
});
$this->ajaxRender(
(string) json_encode([
'success' => true,
])
);
}
/**
* @param \Throwable|\Exception $e
*
* @return void
*/
protected function handleError($e)
{
Logger::getInstance()->error($e);
if ($e instanceof RefreshTokenException) {
$e = $e->getPrevious();
}
if ($e instanceof OAuth2\Exception\ConnectException) {
http_response_code(400);
$this->ajaxRender(
(string) json_encode([
'message' => $e->getMessage(),
'code' => 'oauth-server/connect-error',
//'details' => $e->getDetails(),
])
);
return;
}
if ($e instanceof Accounts\Exception\ConnectException) {
http_response_code(400);
$this->ajaxRender(
(string) json_encode([
'message' => $e->getMessage(),
'code' => 'accounts-api/connect-error',
//'details' => $e->getDetails(),
])
);
return;
}
if ($e instanceof AccountsException) {
http_response_code(400);
$this->ajaxRender(
(string) json_encode([
'message' => $e->getMessage(),
'code' => $e->getErrorCode(),
'details' => $e->getDetails(),
])
);
return;
}
parent::handleError($e);
}
}

View File

@@ -0,0 +1,26 @@
<?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
*/
/**
* @deprecated removed starting ps_accounts 8.0.0
*/
class AdminDebugPsAccountsController extends \ModuleAdminController
{
}

View File

@@ -0,0 +1,26 @@
<?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
*/
/**
* @deprecated removed starting ps_accounts 7.0.0
*/
class AdminLoginController extends \AdminLoginControllerCore
{
}

View File

@@ -0,0 +1,181 @@
<?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
*/
use PrestaShop\Module\PsAccounts\Api\Client\ExternalAssetsClient;
use PrestaShop\Module\PsAccounts\Polyfill\Traits\AdminController\IsAnonymousAllowed;
use PrestaShop\Module\PsAccounts\Service\OAuth2\OAuth2Client;
class AdminLoginPsAccountsController extends \AdminController
{
use IsAnonymousAllowed;
const PARAM_MODE_LOCAL = 'local';
/**
* @var string
*/
public $template = 'login.tpl';
/**
* @var Ps_accounts
*/
public $module;
/**
* @var ExternalAssetsClient
*/
private $externalAssetsClient;
/**
* @throws Exception
*/
public function __construct()
{
$this->bootstrap = true;
parent::__construct();
$this->errors = [];
$this->display_header = false;
/* @phpstan-ignore-next-line */
$this->display_footer = false;
/** @var Ps_accounts $module */
$module = Module::getInstanceByName('ps_accounts');
$this->module = $module;
$this->externalAssetsClient = $this->module->getService(ExternalAssetsClient::class);
if (!headers_sent()) {
header('Login: true');
}
}
/**
* @return void
*/
public function initContent()
{
if ($nb_errors = count($this->errors)) {
$this->context->smarty->assign([
'errors' => $this->errors,
'nbErrors' => $nb_errors,
'shop_name' => Tools::safeOutput((string) Configuration::get('PS_SHOP_NAME')),
'disableDefaultErrorOutPut' => true,
]);
}
$this->setMedia($isNewTheme = false);
$this->initHeader();
parent::initContent();
$this->initFooter();
//force to disable modals
$this->context->smarty->assign('modals', null);
}
/**
* @return bool
*/
public function checkToken()
{
return true;
}
/**
* All BO users can access the login page
*
* @param bool $disable
*
* @return bool
*/
public function viewAccess($disable = false)
{
return true;
}
/**
* @param bool $isNewTheme
*
* @return void
*/
public function setMedia($isNewTheme = false)
{
$this->addCss($this->module->getLocalPath() . '/views/css/login.css' .
'?v=' . urlencode($this->module->version)
);
$this->addJS($this->module->getLocalPath() . '/views/js/login.js' .
'?v=' . urlencode($this->module->version)
);
}
/**
* @param string $tpl_name
*
* @phpstan-ignore-next-line
*
* @return Smarty_Internal_Template
*/
public function createTemplate($tpl_name)
{
/** @var Oauth2Client $oAuth2Client */
$oAuth2Client = $this->module->getService(Oauth2Client::class);
$session = $this->module->getSession();
/* @phpstan-ignore-next-line */
$isoCode = $this->context->currentLocale->getCode();
$this->context->smarty->assign([
/* @phpstan-ignore-next-line */
'shopUrl' => $this->context->shop->getBaseUrl(true),
'oauthRedirectUri' => $oAuth2Client->getRedirectUri(),
'legacyLoginUri' => $this->context->link->getAdminLink(
'AdminLogin', true, [], [
'mode' => self::PARAM_MODE_LOCAL,
]),
'isoCode' => substr($isoCode, 0, 2),
'defaultIsoCode' => 'en',
'testimonials' => $this->getTestimonials(),
'loginError' => $session->remove('loginError'),
'meta_title' => '',
'ssoResendVerificationEmail' => $this->module->getParameter(
'ps_accounts.sso_resend_verification_email_url'
),
]);
/* @phpstan-ignore-next-line */
return $this->context->smarty->createTemplate(
$this->module->getLocalPath() . '/views/templates/admin/' . $this->template,
$this->context->smarty
);
}
/**
* @return array
*/
private function getTestimonials()
{
$res = $this->externalAssetsClient->getTestimonials();
return $res->isSuccessful ? $res->body : [];
}
}

View File

@@ -0,0 +1,310 @@
<?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
*/
require_once __DIR__ . '/../../src/AccountLogin/OAuth2LoginTrait.php';
require_once __DIR__ . '/../../src/Polyfill/Traits/AdminController/IsAnonymousAllowed.php';
use PrestaShop\Module\PsAccounts\Account\Command\IdentifyContactCommand;
use PrestaShop\Module\PsAccounts\AccountLogin\Exception\AccountLoginException;
use PrestaShop\Module\PsAccounts\AccountLogin\Exception\EmailNotVerifiedException;
use PrestaShop\Module\PsAccounts\AccountLogin\Exception\EmployeeNotFoundException;
use PrestaShop\Module\PsAccounts\AccountLogin\OAuth2LoginTrait;
use PrestaShop\Module\PsAccounts\AccountLogin\OAuth2Session;
use PrestaShop\Module\PsAccounts\Cqrs\CommandBus;
use PrestaShop\Module\PsAccounts\Log\Logger;
use PrestaShop\Module\PsAccounts\Polyfill\ConfigurationStorageSession;
use PrestaShop\Module\PsAccounts\Polyfill\Traits\AdminController\IsAnonymousAllowed;
use PrestaShop\Module\PsAccounts\Service\AnalyticsService;
use PrestaShop\Module\PsAccounts\Service\OAuth2\OAuth2Service;
use PrestaShop\Module\PsAccounts\Service\OAuth2\Resource\AccessToken;
use PrestaShop\Module\PsAccounts\Service\PsAccountsService;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class AdminOAuth2PsAccountsController extends \ModuleAdminController
{
use OAuth2LoginTrait;
use IsAnonymousAllowed;
/**
* @var Ps_accounts
*/
public $module;
/**
* @var AnalyticsService
*/
private $analyticsService;
/**
* @var PsAccountsService
*/
private $psAccountsService;
/**
* @var CommandBus
*/
private $commandBus;
/**
* @throws PrestaShopException
* @throws Exception
*/
public function __construct()
{
parent::__construct();
$this->analyticsService = $this->module->getService(AnalyticsService::class);
$this->psAccountsService = $this->module->getService(PsAccountsService::class);
$this->commandBus = $this->module->getService(CommandBus::class);
$this->ajax = true;
$this->content_only = true;
}
/**
* @return bool
*/
public function checkToken()
{
return true;
}
/**
* All BO users can access the login page
*
* @param bool $disable
*
* @return bool
*/
public function viewAccess($disable = false)
{
return true;
}
/**
* @return void
*
* @throws PrestaShopException
*/
//public function display()
public function init()
{
try {
$this->oauth2Login();
} catch (AccountLoginException $e) {
$this->onLoginFailed($e);
} catch (Exception $e) {
$this->onLoginFailed(new AccountLoginException($e->getMessage(), null, $e));
}
// why do this at the end of the method ?
parent::init();
}
/**
* @param AccessToken $accessToken
*
* @return bool
*
* @throws EmailNotVerifiedException
* @throws EmployeeNotFoundException
*/
protected function initUserSession(AccessToken $accessToken)
{
$user = $this->getOAuth2Service()->getUserInfo($accessToken->access_token);
Logger::getInstance()->info(
'[OAuth2] ' . (string) print_r($user, true)
);
if ($this->getOAuthAction() === 'identifyPointOfContact') {
$this->commandBus->handle(
(new IdentifyContactCommand($accessToken, $user))
->withSource($this->getSource())
);
return true;
}
$this->getOauth2Session()->setTokenProvider($accessToken);
//$user = $oauth2Session->getUserInfo();
Logger::getInstance()->info(
'[OAuth2] ' . (string) print_r($user, true)
);
$context = $this->context;
$emailVerified = $user->email_verified;
$context->employee = $this->getEmployeeByUidOrEmail($user->sub, $user->email);
if (!$context->employee->id || empty($emailVerified)) {
$context->employee->logout();
if (empty($emailVerified)) {
throw new EmailNotVerifiedException('Your account email is not verified', $user);
}
throw new EmployeeNotFoundException('The email address is not associated to a PrestaShop backoffice account.', $user);
}
$context->employee->remote_addr = (int) ip2long(Tools::getRemoteAddr());
$cookie = $context->cookie;
/* @phpstan-ignore-next-line */
$cookie->id_employee = $context->employee->id;
/* @phpstan-ignore-next-line */
$cookie->email = $context->employee->email;
/* @phpstan-ignore-next-line */
$cookie->profile = $context->employee->id_profile;
/* @phpstan-ignore-next-line */
$cookie->passwd = $context->employee->passwd;
/* @phpstan-ignore-next-line */
$cookie->remote_addr = $context->employee->remote_addr;
if (class_exists('EmployeeSession') && method_exists($cookie, 'registerSession')) {
$cookie->registerSession(new EmployeeSession());
}
if (!Tools::getValue('stay_logged_in')) {
/* @phpstan-ignore-next-line */
$cookie->last_activity = time();
}
$cookie->write();
$this->trackEditionLoginEvent($user);
return true;
}
/**
* @return OAuth2Service
*
* @throws Exception
*/
protected function getOAuth2Service()
{
return $this->module->getService(OAuth2Service::class);
}
/**
* @return mixed
*/
protected function redirectAfterLogin()
{
if ($this->getOAuthAction() === 'identifyPointOfContact') {
$forceSignup = $this->getForceSignup();
$this->getSession()->clear();
$this->closePopup($forceSignup);
}
$returnTo = $this->getReturnTo() ?: 'AdminDashboard';
if (preg_match('/^([A-Z][a-z0-9]+)+$/', $returnTo)) {
$returnTo = $this->context->link->getAdminLink($returnTo);
}
Tools::redirectAdmin($returnTo);
}
/**
* @return mixed
*/
protected function logout()
{
Tools::redirectAdmin(
$this->context->link->getAdminLink('AdminLogin', true, [], [
'logout' => 1,
])
);
}
/**
* @return mixed
*/
protected function onLoginFailedRedirect()
{
if ($this->getOAuthAction() === 'identifyPointOfContact') {
$this->closePopup();
}
$this->logout();
}
/**
* @return SessionInterface
*/
protected function getSession()
{
if (\Context::getContext()->employee->id) {
// FIXME: fallback only for setPointOfContact
return $this->module->getService(ConfigurationStorageSession::class);
}
return $this->module->getSession();
}
/**
* @return OAuth2Session
*/
protected function getOauth2Session()
{
return $this->module->getService(OAuth2Session::class);
}
/**
* @return AnalyticsService
*/
protected function getAnalyticsService()
{
return $this->analyticsService;
}
/**
* @return PsAccountsService
*/
protected function getPsAccountsService()
{
return $this->psAccountsService;
}
/**
* @param bool $forceSignup
*
* @return void
*/
protected function closePopup($forceSignup = false)
{
if ($forceSignup) {
Tools::redirect($this->getSignupUrl());
} else {
echo '
<script type="text/javascript">
window.close();
</script>
';
exit;
}
}
/**
* @return string
*/
protected function getSignupUrl()
{
return $this->module->getParameter('ps_accounts.accounts_ui_url') .
'?signupContext=popup';
}
}

View File

@@ -0,0 +1,11 @@
<?php
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;