src/Controller/RegistrationController.php line 36

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Constants\MailEventConstants;
  4. use App\Constants\PageTypeConstant;
  5. use App\Constants\UserIpConstants;
  6. use App\Entity\ResetPasswordRequest;
  7. use App\Entity\Tariff;
  8. use App\Entity\User;
  9. use App\Service\KyivstarService;
  10. use App\Service\MailService;
  11. use App\Service\UserIpService;
  12. use App\Repository\BlacklistedDomainRepository;
  13. use Doctrine\Persistence\ManagerRegistry;
  14. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  15. use Symfony\Component\HttpFoundation\Cookie;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  19. use Symfony\Component\Routing\Annotation\Route;
  20. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  21. use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;
  22. use Symfony\Component\Security\Http\Authenticator\FormLoginAuthenticator;
  23. use Symfony\Component\Validator\Validator\ValidatorInterface;
  24. use Symfony\Contracts\Translation\TranslatorInterface;
  25. class RegistrationController extends AbstractController
  26. {
  27.     public function __construct(
  28.         private FormLoginAuthenticator $authenticator
  29.     ) {
  30.     }
  31.     #[Route(path'/register'name'registration_page'methods: ["get""post"])]
  32.     public function registerAction(Request $requestManagerRegistry $managerRegistryValidatorInterface $validatorMailService $mailServiceUserAuthenticatorInterface $userAuthenticatorUserIpService $userIpServiceKyivstarService $kyivstarServiceTranslatorInterface $translator): Response
  33.     {
  34.         if ($this->getUser()) {
  35.             return $this->redirectToRoute('index_page');
  36.         }
  37.         $lifecellSelected $request->cookies->get('lifecellSelected');
  38.         $tariffId $request->cookies->get('tariffSelected');
  39.         if (!$tariffId && !$lifecellSelected) {
  40.             return $this->redirectToRoute('index_page');
  41.         }
  42.         $tariff null;
  43.         if (!$lifecellSelected) {
  44.             $tariff $managerRegistry->getRepository(Tariff::class)->getOneByCompany($tariffId$request->get('companyInner'));
  45.             if (!$tariff) {
  46.                 $response $this->redirectToRoute('index_page');
  47.                 $response->headers->clearCookie('tariffSelected');
  48.                 return $response;
  49.             }
  50.         }
  51.         $submittedToken $request->request->get('_token');
  52.         $company $request->get('companyInner');
  53.         $errors = [];
  54.         if ($request->getMethod() == 'POST' && $this->isCsrfTokenValid('registration'$submittedToken)) {
  55.             $email $request->get('email');
  56.             $now = new \DateTime();
  57.             $user $managerRegistry->getRepository(User::class)->findOneBy(['email'=>$email]);
  58.             $newUser false;
  59.             $userIpService->createUserIpData(UserIpConstants::REGISTER$request, ['email' => $email]);
  60.             if ($user && $user->hasCompany($company)) {
  61.                 return $this->render('pages/register/register.html.twig', [
  62.                     'errors' => $errors,
  63.                     'page' => PageTypeConstant::REGISTRATION,
  64.                     'showLoginPopup' => true,
  65.                     'tariff' => $tariff,
  66.                     'email' => $request->get('email')
  67.                 ]);
  68.             }
  69.             if (!$user) {
  70.                 $newUser true;
  71.                 $user = new User();
  72.                 $user->setEmail($email);
  73.                 $user->setUsername($email);
  74.                 $code rand(1000099999);
  75.                 $user->setVerifyCode($code);
  76.                 $user->setCodeSentAt($now);
  77.                 $user->addRole('ROLE_FRONT_USER');
  78.                 $password bin2hex(openssl_random_pseudo_bytes(4));
  79.                 $user->setPlainPassword($password);
  80.                 $user->setEnabled(true);
  81.             }
  82.             $user->addCompany($company);
  83.             $validatorErrors $validator->validate($user);
  84.             if (count($validatorErrors) == 0) {
  85.                 if ($newUser) {
  86.                     $domain explode('@'$email);
  87.                     if (count($domain) > 1) {
  88.                         $domain end($domain);
  89.                         $forbiddenDomains =  $kyivstarService->getForbiddenDomains();
  90.                         if (!empty($forbiddenDomains)) {
  91.                             if (in_array($domain$forbiddenDomains)) {
  92.                                 $errors['email'] = $translator->trans('email_is_forbidden', [], 'validators');
  93.                                 $this->addFlash('error'$translator->trans('email_is_forbidden', [], 'validators'));
  94.                                 return $this->render('pages/register/register.html.twig', [
  95.                                     'errors' => $errors,
  96.                                     'page' => PageTypeConstant::REGISTRATION,
  97.                                     'tariff' => $tariff,
  98.                                     'email' => $request->get('email')
  99.                                 ]);
  100.                             }
  101.                         }
  102.                          $domainRepository $managerRegistry->getRepository(\App\Entity\BlacklistedDomain::class);
  103.                          if ($domainRepository->isDomainBlacklisted($domain)) {
  104.                             $mailService->sendEmailToUserByCompany(MailEventConstants::REGISTRATION_BLACKLISTED$usernull, ['http_host' => $request->getSchemeAndHttpHost()]);
  105.                             $errors['email'] = $translator->trans('email_is_forbidden', [], 'validators');
  106.                             $this->addFlash('error'$translator->trans('email_is_forbidden', [], 'validators'));
  107.                             return $this->render('pages/register/register.html.twig', [
  108.                                 'errors' => $errors,
  109.                                 'page' => PageTypeConstant::REGISTRATION,
  110.                                 'tariff' => $tariff,
  111.                                 'email' => $request->get('email')
  112.                             ]);
  113.                          }
  114.                     }
  115.                 }
  116.                 $manager $managerRegistry->getManager();
  117.                 $manager->persist($user);
  118.                 $manager->flush($user);
  119.                 $userAuthenticator->authenticateUser(
  120.                     $user,
  121.                     $this->authenticator,
  122.                     $request
  123.                 );
  124.                 if (!$user->getEmailVerifiedAt()) {
  125.                     if ($newUser) {
  126.                         $mailService->sendEmailToUserByCompany(MailEventConstants::REGISTRATION$usernull, ['http_host' => $request->getSchemeAndHttpHost(), 'user_password' => $password]);
  127.                     }
  128.                     $response $this->redirectToRoute('email_verification_page');
  129.                     return $response;
  130.                 }
  131.                 if ($lifecellSelected) {
  132.                     $response $this->redirectToRoute('lifecell_phones_page', ['slug' => $lifecellSelected]);
  133.                 } else {
  134.                     if (!$tariffId) {
  135.                         return $this->redirectToRoute('index_page');
  136.                     }
  137.                     $response $this->redirectToRoute('tariff_phones_page', ['tariff' => $tariffId]);
  138.                 }
  139.                 $response->headers->clearCookie('tariffSelected');
  140.                 $response->headers->clearCookie('lifecellSelected');
  141.                 return $response;
  142.             } else {
  143.                 foreach ($validatorErrors as $error) {
  144.                     $errors[$error->getPropertyPath()] = $error->getMessage();
  145.                 }
  146.             }
  147.         }
  148.         return $this->render('pages/register/register.html.twig', [
  149.             'errors' => $errors,
  150.             'page' => PageTypeConstant::REGISTRATION,
  151.             'tariff' => $tariff,
  152.             'email' => $request->get('email')
  153.         ]);
  154.     }
  155.     #[Route(path'/password/reset'name'password_reset_page'methods: ["get""post"])]
  156.     public function passwordResetLinkAction(Request $requestManagerRegistry $managerRegistryMailService $mailServiceTranslatorInterface $translator): Response
  157.     {
  158.         $submittedToken $request->request->get('_token');
  159.         $errors = [];
  160.         if ($request->getMethod() == 'POST' && $this->isCsrfTokenValid('password-reset'$submittedToken)) {
  161.             $email $request->get('email');
  162.             $manager $managerRegistry->getManager();
  163.             $user $manager->getRepository(User::class)->getOneByCompany($email$request->get('companyInner'));
  164.             if ($user) {
  165.                 $resetUser $managerRegistry->getRepository(ResetPasswordRequest::class)->findOneBy(['email'=>$email]);
  166.                 $now = new \DateTime();
  167.                 if ($resetUser) {
  168.                     $lastResetRequest $resetUser->getCreatedAt();
  169.                     $resendPeriod PageTypeConstant::PASSWORD_RESET_PERIOD;
  170.                     $lastResetRequest->modify("+{$resendPeriod} minutes");
  171.                     if ($now $lastResetRequest) {
  172.                         $dateDiff $now->diff($lastResetRequest);
  173.                         $minutes $dateDiff->days 24 60;
  174.                         $minutes += $dateDiff->60;
  175.                         $minutes += $dateDiff->i;
  176.                         $seconds $dateDiff->s;
  177.                         $seconds sprintf("%02d"$seconds);
  178.                         $errors['email'] = $translator->trans('password_can_be_reset_after', ['%time%' => $minutes.':'.$seconds], 'validators');
  179.                         return $this->render('pages/password_reset/password_reset.html.twig', [
  180.                             'page' => PageTypeConstant::PASSWORD_RESET_PAGE,
  181.                             'errors' => $errors,
  182.                             'email' => $request->get('email')
  183.                         ]);
  184.                     }
  185.                 } else {
  186.                     $resetUser = new ResetPasswordRequest();
  187.                     $resetUser->setEmail($email);
  188.                 }
  189.                 $resetUser->setIp($request->getClientIp());
  190.                 $resetUser->setCreatedAt($now);
  191.                 $manager->persist($resetUser);
  192.                 $manager->flush($resetUser);
  193.                 $token bin2hex(openssl_random_pseudo_bytes(16));
  194.                 $user->setResetHash($token);
  195.                 $manager->flush($user);
  196.                 $mailService->sendEmailToUserByCompany(MailEventConstants::PASSWORD_RESET_LINK$usernull, ['http_host' => $request->getSchemeAndHttpHost()]);
  197.                 $this->addFlash('password_reset_link_success'$user->getEmail());
  198.                 return $this->redirectToRoute('index_page');
  199.             } else {
  200.                 $errors['email'] = $translator->trans('password_reset_user_not_found', [], 'validators');
  201.             }
  202.         }
  203.         $emailFromLogin $request->cookies->get('emailToReset');
  204.         $clearCookie false;
  205.         if ($emailFromLogin) {
  206.             $email $emailFromLogin;
  207.             $clearCookie true;
  208.         } else {
  209.             $email $request->get('email');
  210.         }
  211.         $response $this->render('pages/password_reset/password_reset.html.twig', [
  212.             'page' => PageTypeConstant::PASSWORD_RESET_PAGE,
  213.             'errors' => $errors,
  214.             'email' => $email
  215.         ]);
  216.         if ($clearCookie) {
  217.             $response->headers->clearCookie('emailToReset');
  218.         }
  219.         return $response;
  220.     }
  221.     #[Route(path'/password/reset/{hash}'name'password_reset_link_page'methods: ["get"])]
  222.     public function passwordResetAction(Request $requestManagerRegistry $managerRegistryMailService $mailServiceTranslatorInterface $translator): Response
  223.     {
  224.         $manager $managerRegistry->getManager();
  225.         $user $manager->getRepository(User::class)->getOneByCompanyHash($request->get('hash'), $request->get('companyInner'));
  226.         if ($user) {
  227.             $password bin2hex(openssl_random_pseudo_bytes(4));
  228.             $user->setPlainPassword($password);
  229.             $user->setResetHash(null);
  230.             $now = new \DateTime();
  231.             $user->setEmailVerifiedAt($now);
  232.             $user->setVerifyCode(null);
  233.             $manager->flush($user);
  234.             $mailService->sendEmailToUserByCompany(MailEventConstants::PASSWORD_RESET$usernull, ['http_host' => $request->getSchemeAndHttpHost(), 'user_password' => $password]);
  235.             $this->addFlash('password_reset_success'$user->getEmail());
  236.             return $this->redirectToRoute('index_page');
  237.         }
  238.         throw $this->createNotFoundException();
  239.     }
  240.     #[Route(path'/code/resend'name'code_resend_page'methods: ["post"])]
  241.     public function codeResendAction(Request $requestManagerRegistry $managerRegistryMailService $mailServiceTranslatorInterface $translator): Response
  242.     {
  243.         $user $this->getUser();
  244.         if (!$user) {
  245.             throw new NotFoundHttpException();
  246.         }
  247.         $manager $managerRegistry->getManager();
  248.         $now = new \DateTime();
  249.         $submittedToken $request->request->get('_token');
  250.         //        TODO add verify code to service|helper
  251.         if (($codeSentAt $user->getCodeSentAt()) && $this->isCsrfTokenValid('code-resend'$submittedToken)) {
  252.             $resendPeriod PageTypeConstant::EMAIL_CODE_PERIOD;
  253.             $codeSentAt->modify("+{$resendPeriod} minutes");
  254.             if ($now $codeSentAt || $user->getEmailVerifiedAt()) {
  255.                 $this->addFlash('code_resend_error'$user->getEmail());
  256.             } else {
  257.                 $code rand(1000099999);
  258.                 $user->setVerifyCode($code);
  259.                 $user->setCodeSentAt($now);
  260.                 $manager->flush($user);
  261.                 $mailService->sendEmailToUserByCompany(MailEventConstants::CODE_RESEND$usernull, ['http_host' => $request->getSchemeAndHttpHost()]);
  262.                 $this->addFlash('code_resend_success'$user->getEmail());
  263.             }
  264.         }
  265.         return $this->redirectToRoute('email_verification_page');
  266.     }
  267.     #[Route(path'/email-verification'name'email_verification_page'methods: ["get""post"])]
  268.     public function emailVerificationAction(Request $requestManagerRegistry $managerRegistryTranslatorInterface $translator): Response
  269.     {
  270.         /* @var $user null|User */
  271.         $user $this->getUser();
  272.         if (!$user) {
  273.             throw new NotFoundHttpException();
  274.         }
  275.         $lifecellSelected $request->cookies->get('lifecellSelected');
  276.         $tariffId $request->cookies->get('tariffSelected');
  277.         if ($user->getEmailVerifiedAt()) {
  278.             if ($lifecellSelected) {
  279.                 $response $this->redirectToRoute('lifecell_phones_page', ['slug' => $lifecellSelected]);
  280.                 $response->headers->clearCookie('lifecellSelected');
  281.                 $response->headers->clearCookie('tariffSelected');
  282.             } else {
  283.                 if (!$tariffId) {
  284.                     return $this->redirectToRoute('index_page');
  285.                 }
  286.                 $response $this->redirectToRoute('tariff_phones_page', ['tariff'=>$tariffId]);
  287.                 $response->headers->clearCookie('tariffSelected');
  288.             }
  289.         }
  290.         $submittedToken $request->request->get('_token');
  291.         $errors = [];
  292.         $now = new \DateTime();
  293.         if ($request->getMethod() == 'POST' && $this->isCsrfTokenValid('email-verification'$submittedToken)) {
  294.             $code str_replace('-'''$request->get('code'));
  295.             if ($code == $user->getVerifyCode()) {
  296.                 $manger $managerRegistry->getManager();
  297.                 $user->setEmailVerifiedAt($now);
  298.                 $user->setVerifyCode(null);
  299.                 $manger->flush($user);
  300.                 if ($lifecellSelected) {
  301.                     $response $this->redirectToRoute('lifecell_phones_page', ['slug' => $lifecellSelected]);
  302.                     $response->headers->clearCookie('lifecellSelected');
  303.                     $response->headers->clearCookie('tariffSelected');
  304.                 } else {
  305.                     if (!$tariffId) {
  306.                         return $this->redirectToRoute('index_page');
  307.                     }
  308.                     $response $this->redirectToRoute('tariff_phones_page', ['tariff' => $tariffId]);
  309.                     $response->headers->clearCookie('tariffSelected');
  310.                 }
  311.                 return $response;
  312.             } else {
  313.                 $errors['code'] = $translator->trans('user_email_code_not_valid', [], 'validators');
  314.             }
  315.         }
  316.         $canRequestCodeAt null;
  317.         if ($codeSentAt $user->getCodeSentAt()) {
  318.             $resendPeriod PageTypeConstant::EMAIL_CODE_PERIOD;
  319.             $codeSentAt->modify("+{$resendPeriod} minutes");
  320.             if ($now $codeSentAt) {
  321.                 $dateDiff $now->diff($codeSentAt);
  322.                 $minutes $dateDiff->days 24 60;
  323.                 $minutes += $dateDiff->60;
  324.                 $minutes += $dateDiff->i;
  325.                 $canRequestCodeAt = ['minutes' => $minutes'seconds' => $dateDiff->s];
  326.             }
  327.         }
  328.         $tariff null;
  329.         if ($tariffId) {
  330.             $tariff $managerRegistry->getRepository(Tariff::class)->find($tariffId);
  331.         }
  332.         return $this->render('pages/email_verification/email_verification.html.twig', [
  333.             'user' => $user,
  334.             'tariff' => $tariff,
  335.             'canRequestCodeAt' => $canRequestCodeAt,
  336.             'errors' => $errors,
  337.             'page' => PageTypeConstant::EMAIL_VERIFICATION
  338.         ]);
  339.     }
  340.     #[Route(path'/change-email'name'change_email_page')]
  341.     public function changeEmailAction(Request $requestManagerRegistry $managerRegistryTokenStorageInterface $tokenStorage): Response
  342.     {
  343.         $user $this->getUser();
  344.         if (!$user) {
  345.             $this->redirectToRoute('registration_page');
  346.         }
  347.         $lifecellSelected $request->cookies->get('lifecellSelected');
  348.         $tariffId $request->cookies->get('tariffSelected');
  349.         if ($lifecellSelected) {
  350.             $tokenStorage->setToken();
  351.             $response $this->redirectToRoute('registration_page');
  352.             $response->headers->setCookie(new Cookie('lifecellSelected'$lifecellSelectedtime() + (365 24 60 60)));
  353.             return $response;
  354.         } elseif ($tariffId) {
  355.             $tokenStorage->setToken();
  356.             $response $this->redirectToRoute('registration_page');
  357.             $response->headers->setCookie(new Cookie('tariffSelected'$tariffIdtime() + (365 24 60 60)));
  358.             return $response;
  359.         }
  360.         return $this->redirectToRoute('index_page');
  361.     }
  362. }