custom/plugins/NextagLogin/src/Controller/AuthController.php line 122

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Nextag\Login\Controller;
  4. use Shopware\Core\Checkout\Customer\CustomerEntity;
  5. use Shopware\Storefront\Controller\StorefrontController;
  6. use Shopware\Core\Checkout\Customer\Exception\BadCredentialsException;
  7. use Shopware\Core\Checkout\Customer\Exception\CustomerNotFoundByHashException;
  8. use Shopware\Core\Checkout\Customer\Exception\CustomerNotFoundException;
  9. use Shopware\Core\Checkout\Customer\Exception\CustomerRecoveryHashExpiredException;
  10. use Shopware\Core\Checkout\Customer\Exception\InactiveCustomerException;
  11. use Shopware\Core\Checkout\Customer\SalesChannel\AbstractLoginRoute;
  12. use Shopware\Core\Checkout\Customer\SalesChannel\AbstractLogoutRoute;
  13. use Shopware\Core\Checkout\Customer\SalesChannel\AbstractResetPasswordRoute;
  14. use Shopware\Core\Checkout\Customer\SalesChannel\AbstractSendPasswordRecoveryMailRoute;
  15. use Shopware\Core\Content\Category\Exception\CategoryNotFoundException;
  16. use Shopware\Core\Framework\Context;
  17. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  18. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  19. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  20. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  21. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  22. use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
  23. use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
  24. use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;
  25. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  26. use Shopware\Core\System\SystemConfig\SystemConfigService;
  27. use Shopware\Storefront\Framework\Routing\RequestTransformer;
  28. use Shopware\Storefront\Page\Account\Login\AccountLoginPageLoader;
  29. use Symfony\Component\HttpFoundation\Cookie;
  30. use Symfony\Component\HttpFoundation\Request;
  31. use Symfony\Component\HttpFoundation\Response;
  32. use Symfony\Component\HttpFoundation\JsonResponse;
  33. use Symfony\Component\HttpFoundation\RedirectResponse;
  34. use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
  35. use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
  36. use Symfony\Component\Routing\Annotation\Route;
  37. use Symfony\Component\HttpFoundation\Session\Session;
  38. /**
  39.  * @RouteScope(scopes={"storefront"})
  40.  */
  41. class AuthController extends StorefrontController
  42. {
  43.     /**
  44.      * @var EntityRepositoryInterface
  45.      */
  46.     private $customerRepository;
  47.     /**
  48.      * @var AccountLoginPageLoader
  49.      */
  50.     private $loginPageLoader;
  51.     /**
  52.      * @var EntityRepositoryInterface
  53.      */
  54.     private $customerRecoveryRepository;
  55.     /**
  56.      * @var AbstractSendPasswordRecoveryMailRoute
  57.      */
  58.     private $sendPasswordRecoveryMailRoute;
  59.     /**
  60.      * @var AbstractResetPasswordRoute
  61.      */
  62.     private $resetPasswordRoute;
  63.     /**
  64.      * @var AbstractLoginRoute
  65.      */
  66.     private $loginRoute;
  67.     /**
  68.      * @var AbstractLogoutRoute
  69.      */
  70.     private $logoutRoute;
  71.     
  72.     /**
  73.      * @var SystemConfigService
  74.      */
  75.     private $systemConfig;
  76.     private $cartService;
  77.     private $session;
  78.     private $log;
  79.     public function __construct(
  80.         AccountLoginPageLoader $loginPageLoader,
  81.         EntityRepositoryInterface $customerRecoveryRepository,
  82.         AbstractSendPasswordRecoveryMailRoute $sendPasswordRecoveryMailRoute,
  83.         AbstractResetPasswordRoute $resetPasswordRoute,
  84.         AbstractLoginRoute $loginRoute,
  85.         SystemConfigService $systemConfig,
  86.         AbstractLogoutRoute $logoutRoute,
  87.         CartService $cartService,
  88.         EntityRepositoryInterface $customerRepository,
  89.         Session $session,
  90.         \Nextag\Login\Helper\Log $log
  91.     ) {
  92.         $this->loginPageLoader $loginPageLoader;
  93.         $this->customerRecoveryRepository $customerRecoveryRepository;
  94.         $this->sendPasswordRecoveryMailRoute $sendPasswordRecoveryMailRoute;
  95.         $this->resetPasswordRoute $resetPasswordRoute;
  96.         $this->loginRoute $loginRoute;
  97.         $this->logoutRoute $logoutRoute;
  98.         $this->systemConfig $systemConfig;
  99.         $this->cartService $cartService;
  100.         $this->customerRepository $customerRepository;
  101.         $this->session $session;
  102.         $this->log $log;
  103.     }
  104.     /**
  105.      * @Route("/account/login", name="frontend.account.login.page", methods={"GET"})
  106.      */
  107.     public function loginPage(Request $requestRequestDataBag $dataSalesChannelContext $context): Response
  108.     {
  109.         /** @var string $redirect */
  110.         $redirect $request->get('redirectTo''frontend.account.home.page');
  111.         // if ($context->getCustomer() && $context->getCustomer()->getGuest() == false) {
  112.         //     return $this->createActionResponse($request);
  113.         // }
  114.         $page $this->loginPageLoader->load($request$context);
  115.         return $this->renderStorefront('@Storefront/storefront/page/account/register/index.html.twig', [
  116.             'redirectTo' => $redirect,
  117.             'redirectParameters' => $request->get('redirectParameters'json_encode([])),
  118.             'page' => $page,
  119.             'loginError' => (bool) $request->get('loginError'),
  120.             'errorSnippet' => $request->get('errorSnippet'),
  121.             'data' => $data,
  122.         ]);
  123.     }
  124.     /**
  125.      * @Route("/account/logout", name="frontend.account.logout.page", methods={"GET"})
  126.      */
  127.     public function logout(Request $requestSalesChannelContext $contextRequestDataBag $dataBag): Response
  128.     {
  129.         if ($context->getCustomer() === null) {
  130.             return $this->redirectToRoute('frontend.account.login.page');
  131.         }
  132.         $this->session->set("pos""");
  133.         try {
  134.             $this->logoutRoute->logout($context$dataBag);
  135.             $this->addFlash(self::SUCCESS$this->trans('account.logoutSucceeded'));
  136.             $parameters = [];
  137.         } catch (ConstraintViolationException $formViolations) {
  138.             $parameters = ['formViolations' => $formViolations];
  139.         }
  140.         return $this->redirectToRoute('frontend.account.login.page'$parameters);
  141.     }
  142.     /**
  143.      * @Route("/account/login", name="frontend.account.login", methods={"POST"}, defaults={"XmlHttpRequest"=true})
  144.      */
  145.     public function login(Request $requestRequestDataBag $dataSalesChannelContext $context): Response
  146.     {
  147.         if ($context->getCustomer() && $context->getCustomer()->getGuest() == false) {
  148.             return $this->createActionResponse($request);
  149.         }
  150.         $errorSnippet null;
  151.         // try {
  152.         //     $token = $this->loginRoute->login($data, $context)->getToken();
  153.         //     if (!empty($token)) {
  154.         //         $this->addCartErrors($this->cartService->getCart($token, $context));
  155.         //         return $this->createActionResponse($request);
  156.         //     }
  157.         // } catch (BadCredentialsException | UnauthorizedHttpException | InactiveCustomerException $e) {
  158.         //     if ($e instanceof InactiveCustomerException) {
  159.         //         $errorSnippet = $e->getSnippetKey();
  160.         //     }
  161.         // }
  162.         // $data->set('password', null);
  163.         // return $this->forwardToRoute(
  164.         //     'frontend.account.login.page',
  165.         //     [
  166.         //         'loginError' => true,
  167.         //         'errorSnippet' => $errorSnippet ?? null,
  168.         //     ]
  169.         // );
  170.         try {
  171.             // if ($data->get("password") == "test1234" && $request->get("sw-sales-channel-absolute-base-url") != "https://martel.dev5") {
  172.             //     throw new BadCredentialsException();
  173.             // }
  174.             $email $data->get('email'$data->get('username'));
  175.             $password $data->get('password');
  176.             $token $this->loginRoute->login($data$context)->getToken();
  177.            
  178.             if (!empty($token)) {              
  179.                 $this->log->info("Login von: " $email ." erfolgreich. Token: " $tokenfalse);
  180.                 $this->addCartErrors($this->cartService->getCart($token$context));
  181.                 $loginReferer $data->get("loginReferer");
  182.                 if ($loginReferer && $loginReferer != "") {
  183.                     if (strpos($loginReferer"/account/login")) {
  184.                         $loginReferer explode("/account/login"$loginReferer)[0];
  185.                     }
  186.                     if (strpos($loginReferer"/account/recover/password")) {
  187.                         return $this->redirectToRoute('frontend.account.login.page');
  188.                     }
  189.                     $timestamp date('YmdGis');
  190.                     if (strpos($loginReferer"?")) {
  191.                         $response = new RedirectResponse($loginReferer "&cache=" $timestamp302);
  192.                     } else {
  193.                         $response = new RedirectResponse($loginReferer "?cache=" $timestamp302);
  194.                     }
  195.                     return $response;
  196.                     //return $this->createActionResponse($request);
  197.                 } else {
  198.                     return $this->createActionResponse($request);
  199.                 }
  200.             }
  201.         } catch (BadCredentialsException UnauthorizedHttpException InactiveCustomerException $e) {
  202.             //if ($e instanceof InactiveCustomerException) {
  203.             //    $errorSnippet = $e->getSnippetKey();
  204.             //}
  205.             $this->log->info("Login von: " $email " fehlgeschlagen mit Fehlermeldung: " $e->getMessage(), false);
  206.         }
  207.         $data->set('password'null);
  208.         if ($errorSnippet == null) {
  209.             $this->log->info("Login von: " $email ." fehlgeschlagen"false);
  210.         } else {
  211.             $this->log->info("Login von: " $email " fehlgeschlagen: " json_encode($errorSnippet), false);
  212.         }
  213.         return $this->forwardToRoute(
  214.             'frontend.account.login.page',
  215.             [
  216.                 'loginError' => true,
  217.                 'errorSnippet' => $errorSnippet ?? null,
  218.             ]
  219.         );
  220.     }
  221.     /**
  222.      * @Route("/account/recover", name="frontend.account.recover.page", methods={"GET"})
  223.      *
  224.      * @throws CategoryNotFoundException
  225.      * @throws InconsistentCriteriaIdsException
  226.      * @throws MissingRequestParameterException
  227.      */
  228.     public function recoverAccountForm(Request $requestSalesChannelContext $context): Response
  229.     {
  230.         $page $this->loginPageLoader->load($request$context);
  231.         return $this->renderStorefront('@Storefront/storefront/page/account/profile/recover-password.html.twig', [
  232.             'page' => $page,
  233.         ]);
  234.     }
  235.     /**
  236.      * @Route("/account/emailexists", name="frontend.account.emailexists", methods={"GET"})
  237.      *
  238.      */
  239.     public function checkEmail(Request $requestSalesChannelContext $context): JsonResponse
  240.     {
  241.         $email $request->query->get("email");
  242.         
  243.         $criteria = new Criteria();
  244.         $criteria->addFilter(new EqualsFilter("guest",false));
  245.         $criteria->addFilter(new EqualsFilter("email",$email));
  246.         $customer $this->customerRepository->search($criteria,$context->getContext())->first();
  247.         if ($customer) {
  248.             $response = new JsonResponse(
  249.                 [                
  250.                  'result' => true
  251.                  'email' => $email
  252.                 ],
  253.                 200
  254.             );
  255.         } else {
  256.             $response = new JsonResponse(
  257.                 [                
  258.                  'result' => false,
  259.                 'email' => ''
  260.                 ],
  261.                 200
  262.             );
  263.         }
  264.       
  265.         return $response;
  266.     }
  267.     /**
  268.      * @param string $loginName
  269.      * @param Context $context
  270.      * @return string
  271.      * @throws CustomerNotFoundException
  272.      * @throws \Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException
  273.      */
  274.     private function getCustomerByLoginNameRecovery(string $loginNameSalesChannelContext $context)
  275.     {
  276.         $customField =  $this->systemConfig->get("NextagLogin.config.customField");
  277.         $customer null;
  278.         if ($customField != null && $customField != "") {
  279.             $criteria = new Criteria();
  280.             $criteria->addFilter(new EqualsFilter('guest'0));
  281.             $criteria->addFilter(new EqualsFilter('customFields.' $customField$loginName));
  282.             $criteria->setLimit(1);
  283.             /** @var CustomerEntity $customer */
  284.             $customer $this->customerRepository->search($criteria$context->getContext())->first();
  285.         }
  286.         if (!$customer || !$customer->getEmail()) {
  287.             $criteria = new Criteria();
  288.             $criteria->addFilter(new EqualsFilter('guest'0));
  289.             $criteria->addFilter(new EqualsFilter('email'$loginName));
  290.             $criteria->setLimit(1);
  291.             /** @var CustomerEntity $customer */
  292.             $customer $this->customerRepository->search($criteria$context->getContext())->first();
  293.             if ($customer) {
  294.                 try {
  295.                     if ($customer->getCustomFields() == null) {
  296.                         return $customer;
  297.                     }
  298.                     if ($customer->getCustomFields() && !isset($customer->getCustomFields()[$customField]) || $customer->getCustomFields() && $customer->getCustomFields()[$customField] == $loginName) {
  299.                         return $customer;
  300.                     } else {
  301.                        return null;
  302.                     }
  303.                 } catch (\Exception $exception) {
  304.                     return $customer;
  305.                 }
  306.             } else {
  307.                return null;
  308.             }
  309.         }
  310.         return $customer;
  311.     }
  312.     /**
  313.      * @Route("/account/recover", name="frontend.account.recover.request", methods={"POST"})
  314.      */
  315.     public function generateAccountRecovery(Request $requestRequestDataBag $dataSalesChannelContext $context): Response
  316.     {
  317.         try {
  318.             $accountID $data->get('email')->get("email");
  319.             $customer $this->getCustomerByLoginNameRecovery($accountID$context);
  320.             if ($customer) {
  321.                 $data->get('email')->set("customerId"$customer->get("id"));
  322.                 $data->get('email')->set("email"$customer->get("email"));
  323.                 $data->get('email')->set("accountId"$accountID);
  324.                 $data->get('email')
  325.                     ->set('storefrontUrl'$request->attributes->get(RequestTransformer::STOREFRONT_URL));
  326.                 $this->sendPasswordRecoveryMailRoute->sendRecoveryMail(
  327.                     $data->get('email')->toRequestDataBag(),
  328.                     $context,
  329.                     false
  330.                 );
  331.                 $email $data->get('email')->get('email');
  332.             }
  333.             $this->addFlash('success'$this->trans('account.recoveryMailSend'));
  334.         } catch (CustomerNotFoundException $e) {
  335.             $this->addFlash('success'"");
  336.         } catch (InconsistentCriteriaIdsException $e) {
  337.             $this->addFlash('danger'$this->trans('error.message-default'));
  338.         }
  339.         return $this->redirectToRoute('frontend.account.recover.page');
  340.     }
  341.     /**
  342.      * @Route("/account/recover/password", name="frontend.account.recover.password.page", methods={"GET"})
  343.      *
  344.      * @throws CategoryNotFoundException
  345.      * @throws InconsistentCriteriaIdsException
  346.      * @throws MissingRequestParameterException
  347.      */
  348.     public function resetPasswordForm(Request $requestSalesChannelContext $context): Response
  349.     {
  350.         $page $this->loginPageLoader->load($request$context);
  351.         $hash $request->get('hash');
  352.         if (!$hash) {
  353.             $this->addFlash('danger'$this->trans('account.passwordHashNotFound'));
  354.             return $this->redirectToRoute('frontend.account.recover.request');
  355.         }
  356.         $customerHashCriteria = new Criteria();
  357.         $customerHashCriteria->addFilter(new EqualsFilter('hash'$hash));
  358.         $customerRecovery $this->customerRecoveryRepository
  359.             ->search($customerHashCriteria$context->getContext())
  360.             ->first();
  361.         if ($customerRecovery === null) {
  362.             $this->addFlash('danger'$this->trans('account.passwordHashNotFound'));
  363.             return $this->redirectToRoute('frontend.account.recover.request');
  364.         }
  365.         if (!$this->checkHash($hash$context->getContext())) {
  366.             $this->addFlash('danger'$this->trans('account.passwordHashExpired'));
  367.             return $this->redirectToRoute('frontend.account.recover.request');
  368.         }
  369.         return $this->renderStorefront('@Storefront/storefront/page/account/profile/reset-password.html.twig', [
  370.             'page' => $page,
  371.             'hash' => $hash,
  372.             'formViolations' => $request->get('formViolations'),
  373.         ]);
  374.     }
  375.     /**
  376.      * @Route("/account/recover/password", name="frontend.account.recover.password.reset", methods={"POST"})
  377.      *
  378.      * @throws InconsistentCriteriaIdsException
  379.      */
  380.     public function resetPassword(RequestDataBag $dataSalesChannelContext $context): Response
  381.     {
  382.         $hash $data->get('password')->get('hash');
  383.         try {
  384.             $pw $data->get('password');
  385.             $email "unbekannt";
  386.            
  387.             $customerHashCriteria = new Criteria();
  388.             $customerHashCriteria->addFilter(new EqualsFilter('hash'$hash));
  389.             $customerHashCriteria->addAssociation('customer');
  390.             $customerRecovery $this->customerRecoveryRepository->search($customerHashCriteria$context->getContext())->first();
  391.             if ($customerRecovery) {
  392.                 $customer $customerRecovery->getCustomer();
  393.                 if ($customer) {
  394.                     $email $customer->getEmail();
  395.                 }
  396.             }
  397.             $this->resetPasswordRoute->resetPassword($pw->toRequestDataBag(), $context);
  398.             $this->addFlash('success'$this->trans('account.passwordChangeSuccess'));
  399.             $this->log->info("Passwort reset für: " $email " erfolgreich"false);
  400.         } catch (ConstraintViolationException $formViolations) {
  401.             $this->log->info("Passwort reset für: " $email " nicht erfolgreich (ConstraintViolationException)"false);
  402.             $this->addFlash('danger'$this->trans('account.passwordChangeNoSuccess'));
  403.             return $this->forwardToRoute(
  404.                 'frontend.account.recover.password.page',
  405.                 ['hash' => $hash'formViolations' => $formViolations'passwordFormViolation' => true]
  406.             );
  407.         } catch (CustomerNotFoundByHashException $e) {
  408.             $this->log->info("Passwort reset für: " $email " nicht erfolgreich (CustomerNotFoundByHashException)"false);
  409.             $this->addFlash('danger'$this->trans('account.passwordChangeNoSuccess'));
  410.             return $this->forwardToRoute('frontend.account.recover.request');
  411.         } catch (CustomerRecoveryHashExpiredException $e) {
  412.             $this->log->info("Passwort reset für: " $email " nicht erfolgreich (CustomerRecoveryHashExpiredException)"false);
  413.             $this->addFlash('danger'$this->trans('account.passwordHashExpired'));
  414.             return $this->forwardToRoute('frontend.account.recover.request');
  415.         }
  416.         return $this->redirectToRoute('frontend.account.login.page');
  417.     }
  418.     private function checkHash(string $hashContext $context): bool
  419.     {
  420.         $criteria = new Criteria();
  421.         $criteria->addFilter(new EqualsFilter('hash'$hash));
  422.         $recovery $this->customerRecoveryRepository->search($criteria$context)->first();
  423.         $validDateTime = (new \DateTime())->sub(new \DateInterval('PT2H'));
  424.         return $recovery && $validDateTime $recovery->getCreatedAt();
  425.     }
  426. }