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

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