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

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\CustomerAuthThrottledException;
  5. use Shopware\Core\Checkout\Customer\Exception\CustomerNotFoundByHashException;
  6. use Shopware\Core\Checkout\Customer\Exception\CustomerNotFoundException;
  7. use Shopware\Core\Checkout\Customer\Exception\CustomerRecoveryHashExpiredException;
  8. use Shopware\Core\Checkout\Customer\Exception\InactiveCustomerException;
  9. use Shopware\Core\Checkout\Customer\SalesChannel\AbstractLoginRoute;
  10. use Shopware\Core\Checkout\Customer\SalesChannel\AbstractLogoutRoute;
  11. use Shopware\Core\Checkout\Customer\SalesChannel\AbstractResetPasswordRoute;
  12. use Shopware\Core\Checkout\Customer\SalesChannel\AbstractSendPasswordRecoveryMailRoute;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  14. use Shopware\Core\Framework\Feature;
  15. use Shopware\Core\Framework\RateLimiter\Exception\RateLimitExceededException;
  16. use Shopware\Core\Framework\Routing\Annotation\Since;
  17. use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
  18. use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;
  19. use Shopware\Core\PlatformRequest;
  20. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceInterface;
  21. use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceParameters;
  22. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  23. use Shopware\Storefront\Checkout\Cart\SalesChannel\StorefrontCartFacade;
  24. use Shopware\Storefront\Framework\Routing\Annotation\NoStore;
  25. use Shopware\Storefront\Framework\Routing\RequestTransformer;
  26. use Shopware\Storefront\Page\Account\Login\AccountGuestLoginPageLoadedHook;
  27. use Shopware\Storefront\Page\Account\Login\AccountLoginPageLoadedHook;
  28. use Shopware\Storefront\Page\Account\Login\AccountLoginPageLoader;
  29. use Shopware\Storefront\Page\Account\RecoverPassword\AccountRecoverPasswordPage;
  30. use Shopware\Storefront\Page\Account\RecoverPassword\AccountRecoverPasswordPageLoadedHook;
  31. use Shopware\Storefront\Page\Account\RecoverPassword\AccountRecoverPasswordPageLoader;
  32. use Symfony\Component\HttpFoundation\Request;
  33. use Symfony\Component\HttpFoundation\Response;
  34. use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
  35. use Symfony\Component\Routing\Annotation\Route;
  36. /**
  37.  * @Route(defaults={"_routeScope"={"storefront"}})
  38.  *
  39.  * @deprecated tag:v6.5.0 - reason:becomes-internal - Will be internal
  40.  */
  41. class AuthController extends StorefrontController
  42. {
  43.     private AccountLoginPageLoader $loginPageLoader;
  44.     private AbstractSendPasswordRecoveryMailRoute $sendPasswordRecoveryMailRoute;
  45.     private AbstractResetPasswordRoute $resetPasswordRoute;
  46.     private AbstractLoginRoute $loginRoute;
  47.     private AbstractLogoutRoute $logoutRoute;
  48.     private StorefrontCartFacade $cartFacade;
  49.     private AccountRecoverPasswordPageLoader $recoverPasswordPageLoader;
  50.     private SalesChannelContextServiceInterface $salesChannelContext;
  51.     /**
  52.      * @internal
  53.      */
  54.     public function __construct(
  55.         AccountLoginPageLoader $loginPageLoader,
  56.         AbstractSendPasswordRecoveryMailRoute $sendPasswordRecoveryMailRoute,
  57.         AbstractResetPasswordRoute $resetPasswordRoute,
  58.         AbstractLoginRoute $loginRoute,
  59.         AbstractLogoutRoute $logoutRoute,
  60.         StorefrontCartFacade $cartFacade,
  61.         AccountRecoverPasswordPageLoader $recoverPasswordPageLoader,
  62.         SalesChannelContextServiceInterface $salesChannelContextService
  63.     ) {
  64.         $this->loginPageLoader $loginPageLoader;
  65.         $this->sendPasswordRecoveryMailRoute $sendPasswordRecoveryMailRoute;
  66.         $this->resetPasswordRoute $resetPasswordRoute;
  67.         $this->loginRoute $loginRoute;
  68.         $this->logoutRoute $logoutRoute;
  69.         $this->cartFacade $cartFacade;
  70.         $this->recoverPasswordPageLoader $recoverPasswordPageLoader;
  71.         $this->salesChannelContext $salesChannelContextService;
  72.     }
  73.     /**
  74.      * @Since("6.0.0.0")
  75.      * @Route("/account/login", name="frontend.account.login.page", methods={"GET"})
  76.      * @NoStore
  77.      */
  78.     public function loginPage(Request $requestRequestDataBag $dataSalesChannelContext $context): Response
  79.     {
  80.         /** @var string $redirect */
  81.         $redirect $request->get('redirectTo''frontend.account.home.page');
  82.         $customer $context->getCustomer();
  83.         if ($customer !== null && $customer->getGuest() === false) {
  84.             $request->request->set('redirectTo'$redirect);
  85.             return $this->createActionResponse($request);
  86.         }
  87.         $page $this->loginPageLoader->load($request$context);
  88.         $this->hook(new AccountLoginPageLoadedHook($page$context));
  89.         return $this->renderStorefront('@Storefront/storefront/page/account/register/index.html.twig', [
  90.             'redirectTo' => $redirect,
  91.             'redirectParameters' => $request->get('redirectParameters'json_encode([])),
  92.             'page' => $page,
  93.             'loginError' => (bool) $request->get('loginError'),
  94.             'waitTime' => $request->get('waitTime'),
  95.             'errorSnippet' => $request->get('errorSnippet'),
  96.             'data' => $data,
  97.         ]);
  98.     }
  99.     /**
  100.      * @Since("6.3.4.1")
  101.      * @Route("/account/guest/login", name="frontend.account.guest.login.page", methods={"GET"})
  102.      * @NoStore
  103.      */
  104.     public function guestLoginPage(Request $requestSalesChannelContext $context): Response
  105.     {
  106.         /** @var string $redirect */
  107.         $redirect $request->get('redirectTo''frontend.account.home.page');
  108.         $customer $context->getCustomer();
  109.         if ($customer !== null) {
  110.             $request->request->set('redirectTo'$redirect);
  111.             return $this->createActionResponse($request);
  112.         }
  113.         $waitTime = (int) $request->get('waitTime');
  114.         if ($waitTime) {
  115.             $this->addFlash(self::INFO$this->trans('account.loginThrottled', ['%seconds%' => $waitTime]));
  116.         }
  117.         if ((bool) $request->get('loginError')) {
  118.             $this->addFlash(self::DANGER$this->trans('account.orderGuestLoginWrongCredentials'));
  119.         }
  120.         $page $this->loginPageLoader->load($request$context);
  121.         $this->hook(new AccountGuestLoginPageLoadedHook($page$context));
  122.         return $this->renderStorefront('@Storefront/storefront/page/account/guest-auth.html.twig', [
  123.             'redirectTo' => $redirect,
  124.             'redirectParameters' => $request->get('redirectParameters'json_encode([])),
  125.             'page' => $page,
  126.         ]);
  127.     }
  128.     /**
  129.      * @Since("6.0.0.0")
  130.      * @Route("/account/logout", name="frontend.account.logout.page", methods={"GET"})
  131.      */
  132.     public function logout(Request $requestSalesChannelContext $contextRequestDataBag $dataBag): Response
  133.     {
  134.         if ($context->getCustomer() === null) {
  135.             return $this->redirectToRoute('frontend.account.login.page');
  136.         }
  137.         try {
  138.             $this->logoutRoute->logout($context$dataBag);
  139.             $this->addFlash(self::SUCCESS$this->trans('account.logoutSucceeded'));
  140.             $parameters = [];
  141.         } catch (ConstraintViolationException $formViolations) {
  142.             $parameters = ['formViolations' => $formViolations];
  143.         }
  144.         return $this->redirectToRoute('frontend.account.login.page'$parameters);
  145.     }
  146.     /**
  147.      * @Since("6.0.0.0")
  148.      * @Route("/account/login", name="frontend.account.login", methods={"POST"}, defaults={"XmlHttpRequest"=true})
  149.      */
  150.     public function login(Request $requestRequestDataBag $dataSalesChannelContext $context): Response
  151.     {
  152.         $customer $context->getCustomer();
  153.         if ($customer !== null && $customer->getGuest() === false) {
  154.             return $this->createActionResponse($request);
  155.         }
  156.         try {
  157.             $token $this->loginRoute->login($data$context)->getToken();
  158.             $cartBeforeNewContext $this->cartFacade->get($token$context);
  159.             $newContext $this->salesChannelContext->get(
  160.                 new SalesChannelContextServiceParameters(
  161.                     $context->getSalesChannelId(),
  162.                     $token,
  163.                     $context->getLanguageIdChain()[0],
  164.                     $context->getCurrencyId(),
  165.                     $context->getDomainId(),
  166.                     $context->getContext()
  167.                 )
  168.             );
  169.             // Update the sales channel context for CacheResponseSubscriber
  170.             $request->attributes->set(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT$newContext);
  171.             if (!empty($token)) {
  172.                 $this->addCartErrors($cartBeforeNewContext);
  173.                 return $this->createActionResponse($request);
  174.             }
  175.         } catch (BadCredentialsException UnauthorizedHttpException InactiveCustomerException CustomerAuthThrottledException $e) {
  176.             if ($e instanceof InactiveCustomerException) {
  177.                 $errorSnippet $e->getSnippetKey();
  178.             }
  179.             if ($e instanceof CustomerAuthThrottledException) {
  180.                 $waitTime $e->getWaitTime();
  181.             }
  182.         }
  183.         $data->set('password'null);
  184.         return $this->forwardToRoute(
  185.             'frontend.account.login.page',
  186.             [
  187.                 'loginError' => true,
  188.                 'errorSnippet' => $errorSnippet ?? null,
  189.                 'waitTime' => $waitTime ?? null,
  190.             ]
  191.         );
  192.     }
  193.     /**
  194.      * @Since("6.1.0.0")
  195.      * @Route("/account/recover", name="frontend.account.recover.page", methods={"GET"})
  196.      */
  197.     public function recoverAccountForm(Request $requestSalesChannelContext $context): Response
  198.     {
  199.         $page $this->loginPageLoader->load($request$context);
  200.         return $this->renderStorefront('@Storefront/storefront/page/account/profile/recover-password.html.twig', [
  201.             'page' => $page,
  202.         ]);
  203.     }
  204.     /**
  205.      * @Since("6.1.0.0")
  206.      * @Route("/account/recover", name="frontend.account.recover.request", methods={"POST"})
  207.      */
  208.     public function generateAccountRecovery(Request $requestRequestDataBag $dataSalesChannelContext $context): Response
  209.     {
  210.         try {
  211.             $data->get('email')
  212.                 ->set('storefrontUrl'$request->attributes->get(RequestTransformer::STOREFRONT_URL));
  213.             $this->sendPasswordRecoveryMailRoute->sendRecoveryMail(
  214.                 $data->get('email')->toRequestDataBag(),
  215.                 $context,
  216.                 false
  217.             );
  218.             $this->addFlash(self::SUCCESS$this->trans('account.recoveryMailSend'));
  219.         } catch (CustomerNotFoundException $e) {
  220.             $this->addFlash(self::SUCCESS$this->trans('account.recoveryMailSend'));
  221.         } catch (InconsistentCriteriaIdsException $e) {
  222.             $this->addFlash(self::DANGER$this->trans('error.message-default'));
  223.         } catch (RateLimitExceededException $e) {
  224.             $this->addFlash(self::INFO$this->trans('error.rateLimitExceeded', ['%seconds%' => $e->getWaitTime()]));
  225.         }
  226.         return $this->redirectToRoute('frontend.account.recover.page');
  227.     }
  228.     /**
  229.      * @Since("6.1.0.0")
  230.      * @Route("/account/recover/password", name="frontend.account.recover.password.page", methods={"GET"})
  231.      */
  232.     public function resetPasswordForm(Request $requestSalesChannelContext $context): Response
  233.     {
  234.         /** @deprecated tag:v6.5.0 - call to loginPageLoader and $loginPage will be removed */
  235.         $loginPage null;
  236.         if (!Feature::isActive('v6.5.0.0')) {
  237.             $loginPage $this->loginPageLoader->load($request$context);
  238.         }
  239.         /** @var ?string $hash */
  240.         $hash $request->get('hash');
  241.         if (!$hash || !\is_string($hash)) {
  242.             $this->addFlash(self::DANGER$this->trans('account.passwordHashNotFound'));
  243.             return $this->redirectToRoute('frontend.account.recover.request');
  244.         }
  245.         try {
  246.             $page $this->recoverPasswordPageLoader->load($request$context$hash);
  247.         } catch (ConstraintViolationException $e) {
  248.             $this->addFlash(self::DANGER$this->trans('account.passwordHashNotFound'));
  249.             return $this->redirectToRoute('frontend.account.recover.request');
  250.         }
  251.         $this->hook(new AccountRecoverPasswordPageLoadedHook($page$context));
  252.         if ($page->getHash() === null || $page->isHashExpired()) {
  253.             $this->addFlash(self::DANGER$this->trans('account.passwordHashNotFound'));
  254.             return $this->redirectToRoute('frontend.account.recover.request');
  255.         }
  256.         if (Feature::isActive('v6.5.0.0')) {
  257.             return $this->renderStorefront('@Storefront/storefront/page/account/profile/reset-password.html.twig', [
  258.                 'page' => $page,
  259.                 'formViolations' => $request->get('formViolations'),
  260.             ]);
  261.         }
  262.         /** @deprecated tag:v6.5.0 - page will be instance of AccountRecoverPasswordPage and $hash will be moved to $page.getHash() */
  263.         return $this->renderStorefront('@Storefront/storefront/page/account/profile/reset-password.html.twig', [
  264.             'page' => $loginPage,
  265.             'hash' => $hash,
  266.             'formViolations' => $request->get('formViolations'),
  267.         ]);
  268.     }
  269.     /**
  270.      * @Since("6.1.0.0")
  271.      * @Route("/account/recover/password", name="frontend.account.recover.password.reset", methods={"POST"})
  272.      */
  273.     public function resetPassword(RequestDataBag $dataSalesChannelContext $context): Response
  274.     {
  275.         $hash $data->get('password')->get('hash');
  276.         try {
  277.             $pw $data->get('password');
  278.             $this->resetPasswordRoute->resetPassword($pw->toRequestDataBag(), $context);
  279.             $this->addFlash(self::SUCCESS$this->trans('account.passwordChangeSuccess'));
  280.         } catch (ConstraintViolationException $formViolations) {
  281.             $this->addFlash(self::DANGER$this->trans('account.passwordChangeNoSuccess'));
  282.             return $this->forwardToRoute(
  283.                 'frontend.account.recover.password.page',
  284.                 ['hash' => $hash'formViolations' => $formViolations'passwordFormViolation' => true]
  285.             );
  286.         } catch (CustomerNotFoundByHashException $e) {
  287.             $this->addFlash(self::DANGER$this->trans('account.passwordChangeNoSuccess'));
  288.             return $this->forwardToRoute('frontend.account.recover.request');
  289.         } catch (CustomerRecoveryHashExpiredException $e) {
  290.             $this->addFlash(self::DANGER$this->trans('account.passwordHashExpired'));
  291.             return $this->forwardToRoute('frontend.account.recover.request');
  292.         }
  293.         return $this->redirectToRoute('frontend.account.profile.page');
  294.     }
  295. }