vendor/shopware/storefront/Controller/AuthController.php line 179

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Storefront\Controller;
  3. use Shopware\Core\Checkout\Customer\Exception\BadCredentialsException;
  4. use Shopware\Core\Checkout\Customer\Exception\CustomerNotFoundByHashException;
  5. use Shopware\Core\Checkout\Customer\Exception\CustomerNotFoundException;
  6. use Shopware\Core\Checkout\Customer\Exception\CustomerRecoveryHashExpiredException;
  7. use Shopware\Core\Checkout\Customer\Exception\InactiveCustomerException;
  8. use Shopware\Core\Checkout\Customer\SalesChannel\AbstractLoginRoute;
  9. use Shopware\Core\Checkout\Customer\SalesChannel\AbstractLogoutRoute;
  10. use Shopware\Core\Checkout\Customer\SalesChannel\AbstractResetPasswordRoute;
  11. use Shopware\Core\Checkout\Customer\SalesChannel\AbstractSendPasswordRecoveryMailRoute;
  12. use Shopware\Core\Content\Category\Exception\CategoryNotFoundException;
  13. use Shopware\Core\Framework\Context;
  14. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  17. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  18. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  19. use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
  20. use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
  21. use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;
  22. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  23. use Shopware\Core\System\SystemConfig\SystemConfigService;
  24. use Shopware\Storefront\Framework\Routing\RequestTransformer;
  25. use Shopware\Storefront\Page\Account\Login\AccountLoginPageLoader;
  26. use Symfony\Component\HttpFoundation\Request;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
  29. use Symfony\Component\Routing\Annotation\Route;
  30. /**
  31.  * @RouteScope(scopes={"storefront"})
  32.  */
  33. class AuthController extends StorefrontController
  34. {
  35.     /**
  36.      * @var AccountLoginPageLoader
  37.      */
  38.     private $loginPageLoader;
  39.     /**
  40.      * @var EntityRepositoryInterface
  41.      */
  42.     private $customerRecoveryRepository;
  43.     /**
  44.      * @var AbstractSendPasswordRecoveryMailRoute
  45.      */
  46.     private $sendPasswordRecoveryMailRoute;
  47.     /**
  48.      * @var AbstractResetPasswordRoute
  49.      */
  50.     private $resetPasswordRoute;
  51.     /**
  52.      * @var AbstractLoginRoute
  53.      */
  54.     private $loginRoute;
  55.     /**
  56.      * @var AbstractLogoutRoute
  57.      */
  58.     private $logoutRoute;
  59.     /**
  60.      * @var SystemConfigService
  61.      */
  62.     private $systemConfig;
  63.     public function __construct(
  64.         AccountLoginPageLoader $loginPageLoader,
  65.         EntityRepositoryInterface $customerRecoveryRepository,
  66.         AbstractSendPasswordRecoveryMailRoute $sendPasswordRecoveryMailRoute,
  67.         AbstractResetPasswordRoute $resetPasswordRoute,
  68.         AbstractLoginRoute $loginRoute,
  69.         SystemConfigService $systemConfig,
  70.         AbstractLogoutRoute $logoutRoute
  71.     ) {
  72.         $this->loginPageLoader $loginPageLoader;
  73.         $this->customerRecoveryRepository $customerRecoveryRepository;
  74.         $this->sendPasswordRecoveryMailRoute $sendPasswordRecoveryMailRoute;
  75.         $this->resetPasswordRoute $resetPasswordRoute;
  76.         $this->loginRoute $loginRoute;
  77.         $this->logoutRoute $logoutRoute;
  78.         $this->systemConfig $systemConfig;
  79.     }
  80.     /**
  81.      * @Route("/account/login", name="frontend.account.login.page", methods={"GET"})
  82.      */
  83.     public function loginPage(Request $requestRequestDataBag $dataSalesChannelContext $context): Response
  84.     {
  85.         /** @var string $redirect */
  86.         $redirect $request->get('redirectTo''frontend.account.home.page');
  87.         if ($context->getCustomer()) {
  88.             return $this->createActionResponse($request);
  89.         }
  90.         $page $this->loginPageLoader->load($request$context);
  91.         return $this->renderStorefront('@Storefront/storefront/page/account/register/index.html.twig', [
  92.             'redirectTo' => $redirect,
  93.             'redirectParameters' => $request->get('redirectParameters'json_encode([])),
  94.             'page' => $page,
  95.             'loginError' => (bool) $request->get('loginError'),
  96.             'errorSnippet' => $request->get('errorSnippet'),
  97.             'data' => $data,
  98.         ]);
  99.     }
  100.     /**
  101.      * @Route("/account/logout", name="frontend.account.logout.page", methods={"GET"})
  102.      */
  103.     public function logout(Request $requestSalesChannelContext $context): Response
  104.     {
  105.         if ($context->getCustomer() === null) {
  106.             return $this->redirectToRoute('frontend.account.login.page');
  107.         }
  108.         try {
  109.             $this->logoutRoute->logout($context);
  110.             $salesChannelId $context->getSalesChannel()->getId();
  111.             if ($request->hasSession() && $this->systemConfig->get('core.loginRegistration.invalidateSessionOnLogOut'$salesChannelId)) {
  112.                 $request->getSession()->invalidate();
  113.             }
  114.             $this->addFlash('success'$this->trans('account.logoutSucceeded'));
  115.             $parameters = [];
  116.         } catch (ConstraintViolationException $formViolations) {
  117.             $parameters = ['formViolations' => $formViolations];
  118.         }
  119.         return $this->redirectToRoute('frontend.account.login.page'$parameters);
  120.     }
  121.     /**
  122.      * @Route("/account/login", name="frontend.account.login", methods={"POST"}, defaults={"XmlHttpRequest"=true})
  123.      */
  124.     public function login(Request $requestRequestDataBag $dataSalesChannelContext $context): Response
  125.     {
  126.         if ($context->getCustomer()) {
  127.             return $this->createActionResponse($request);
  128.         }
  129.         try {
  130.             $token $this->loginRoute->login($data$context)->getToken();
  131.             if (!empty($token)) {
  132.                 return $this->createActionResponse($request);
  133.             }
  134.         } catch (BadCredentialsException UnauthorizedHttpException InactiveCustomerException $e) {
  135.             if ($e instanceof InactiveCustomerException) {
  136.                 $errorSnippet $e->getSnippetKey();
  137.             }
  138.         }
  139.         $data->set('password'null);
  140.         return $this->forwardToRoute(
  141.             'frontend.account.login.page',
  142.             [
  143.                 'loginError' => true,
  144.                 'errorSnippet' => $errorSnippet ?? null,
  145.             ]
  146.         );
  147.     }
  148.     /**
  149.      * @Route("/account/recover", name="frontend.account.recover.page", methods={"GET"})
  150.      *
  151.      * @throws CategoryNotFoundException
  152.      * @throws InconsistentCriteriaIdsException
  153.      * @throws MissingRequestParameterException
  154.      */
  155.     public function recoverAccountForm(Request $requestSalesChannelContext $context): Response
  156.     {
  157.         $page $this->loginPageLoader->load($request$context);
  158.         return $this->renderStorefront('@Storefront/storefront/page/account/profile/recover-password.html.twig', [
  159.             'page' => $page,
  160.         ]);
  161.     }
  162.     /**
  163.      * @Route("/account/recover", name="frontend.account.recover.request", methods={"POST"})
  164.      */
  165.     public function generateAccountRecovery(Request $requestRequestDataBag $dataSalesChannelContext $context): Response
  166.     {
  167.         try {
  168.             $data->get('email')
  169.                 ->set('storefrontUrl'$request->attributes->get(RequestTransformer::STOREFRONT_URL));
  170.             $this->sendPasswordRecoveryMailRoute->sendRecoveryMail(
  171.                 $data->get('email')->toRequestDataBag(),
  172.                 $context,
  173.                 false
  174.             );
  175.             $this->addFlash('success'$this->trans('account.recoveryMailSend'));
  176.         } catch (CustomerNotFoundException $e) {
  177.             $this->addFlash('success'$this->trans('account.recoveryMailSend'));
  178.         } catch (InconsistentCriteriaIdsException $e) {
  179.             $this->addFlash('danger'$this->trans('error.message-default'));
  180.         }
  181.         return $this->redirectToRoute('frontend.account.recover.page');
  182.     }
  183.     /**
  184.      * @Route("/account/recover/password", name="frontend.account.recover.password.page", methods={"GET"})
  185.      *
  186.      * @throws CategoryNotFoundException
  187.      * @throws InconsistentCriteriaIdsException
  188.      * @throws MissingRequestParameterException
  189.      */
  190.     public function resetPasswordForm(Request $requestSalesChannelContext $context): Response
  191.     {
  192.         $page $this->loginPageLoader->load($request$context);
  193.         $hash $request->get('hash');
  194.         if (!$hash) {
  195.             $this->addFlash('danger'$this->trans('account.passwordHashNotFound'));
  196.             return $this->redirectToRoute('frontend.account.recover.request');
  197.         }
  198.         $customerHashCriteria = new Criteria();
  199.         $customerHashCriteria->addFilter(new EqualsFilter('hash'$hash));
  200.         $customerRecovery $this->customerRecoveryRepository
  201.             ->search($customerHashCriteria$context->getContext())
  202.             ->first();
  203.         if ($customerRecovery === null) {
  204.             $this->addFlash('danger'$this->trans('account.passwordHashNotFound'));
  205.             return $this->redirectToRoute('frontend.account.recover.request');
  206.         }
  207.         if (!$this->checkHash($hash$context->getContext())) {
  208.             $this->addFlash('danger'$this->trans('account.passwordHashExpired'));
  209.             return $this->redirectToRoute('frontend.account.recover.request');
  210.         }
  211.         return $this->renderStorefront('@Storefront/storefront/page/account/profile/reset-password.html.twig', [
  212.             'page' => $page,
  213.             'hash' => $hash,
  214.             'formViolations' => $request->get('formViolations'),
  215.         ]);
  216.     }
  217.     /**
  218.      * @Route("/account/recover/password", name="frontend.account.recover.password.reset", methods={"POST"})
  219.      *
  220.      * @throws InconsistentCriteriaIdsException
  221.      */
  222.     public function resetPassword(RequestDataBag $dataSalesChannelContext $context): Response
  223.     {
  224.         $hash $data->get('password')->get('hash');
  225.         try {
  226.             $pw $data->get('password');
  227.             $this->resetPasswordRoute->resetPassword($pw->toRequestDataBag(), $context);
  228.             $this->addFlash('success'$this->trans('account.passwordChangeSuccess'));
  229.         } catch (ConstraintViolationException $formViolations) {
  230.             $this->addFlash('danger'$this->trans('account.passwordChangeNoSuccess'));
  231.             return $this->forwardToRoute(
  232.                 'frontend.account.recover.password.page',
  233.                 ['hash' => $hash'formViolations' => $formViolations'passwordFormViolation' => true]
  234.             );
  235.         } catch (CustomerNotFoundByHashException $e) {
  236.             $this->addFlash('danger'$this->trans('account.passwordChangeNoSuccess'));
  237.             return $this->forwardToRoute('frontend.account.recover.request');
  238.         } catch (CustomerRecoveryHashExpiredException $e) {
  239.             $this->addFlash('danger'$this->trans('account.passwordHashExpired'));
  240.             return $this->forwardToRoute('frontend.account.recover.request');
  241.         }
  242.         return $this->redirectToRoute('frontend.account.profile.page');
  243.     }
  244.     private function checkHash(string $hashContext $context): bool
  245.     {
  246.         $criteria = new Criteria();
  247.         $criteria->addFilter(new EqualsFilter('hash'$hash));
  248.         $recovery $this->customerRecoveryRepository->search($criteria$context)->first();
  249.         $validDateTime = (new \DateTime())->sub(new \DateInterval('PT2H'));
  250.         return $recovery && $validDateTime $recovery->getCreatedAt();
  251.     }
  252. }