src/Controller/ResetPasswordController.php line 66

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Users;
  4. use App\Entity\PublisherCabinet\MafoPublisherCabinetManager;
  5. use App\Entity\AdvertiserCabinet\MafoAdvertiserCabinetManager;
  6. use App\Form\ChangePasswordFormType;
  7. use App\Form\ResetPasswordRequestFormType;
  8. use Doctrine\ORM\EntityManagerInterface;
  9. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  10. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  11. use Symfony\Component\Form\Extension\Core\Type\PasswordType;
  12. use Symfony\Component\HttpFoundation\RedirectResponse;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Response;
  15. use Symfony\Component\Mailer\MailerInterface;
  16. use Symfony\Component\Mime\Address;
  17. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  18. use Symfony\Component\Routing\Annotation\Route;
  19. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  20. use Symfony\Contracts\Translation\TranslatorInterface;
  21. use SymfonyCasts\Bundle\ResetPassword\Controller\ResetPasswordControllerTrait;
  22. use SymfonyCasts\Bundle\ResetPassword\Exception\ResetPasswordExceptionInterface;
  23. use SymfonyCasts\Bundle\ResetPassword\ResetPasswordHelperInterface;
  24. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  25. /**
  26.  * @Route("/reset-password", name="reset_password_")
  27.  */
  28. class ResetPasswordController extends AbstractController
  29. {
  30.     use ResetPasswordControllerTrait;
  31.     private ResetPasswordHelperInterface $userResetPasswordHelper;
  32.     private ResetPasswordHelperInterface $mafoPublisherResetPasswordHelper;
  33.     private ResetPasswordHelperInterface $mafoAdvertiserResetPasswordHelper;
  34.     private EntityManagerInterface $entityManager;
  35.     private $params;
  36.     private string $publisherDomain;
  37.     private string $advertiserDomain;
  38.     public function __construct(
  39.         ResetPasswordHelperInterface $userResetPasswordHelper,
  40.         ResetPasswordHelperInterface $mafoPublisherResetPasswordHelper,
  41.         ResetPasswordHelperInterface $mafoAdvertiserResetPasswordHelper,
  42.         EntityManagerInterface $entityManager,
  43.         ParameterBagInterface $params,
  44.     ) {
  45.         $this->userResetPasswordHelper $userResetPasswordHelper;
  46.         $this->mafoPublisherResetPasswordHelper $mafoPublisherResetPasswordHelper;
  47.         $this->mafoAdvertiserResetPasswordHelper $mafoAdvertiserResetPasswordHelper;
  48.         $this->entityManager $entityManager;
  49.         $this->params $params;
  50.         $this->publisherDomain $params->get('publishers_subdomain');
  51.         $this->advertiserDomain $params->get('advertisers_subdomain');
  52.     }
  53.     /**
  54.      * Display & process form to request a password reset.
  55.      *
  56.      * @Route("", name="app_forgot_password_request")
  57.      */
  58.     public function request(Request $requestMailerInterface $mailerTranslatorInterface $translator): Response
  59.     {
  60.         $form $this->createForm(ResetPasswordRequestFormType::class);
  61.         $form->handleRequest($request);
  62.         // Get the current domain from the request
  63.         $domain $request->getHost();
  64.         $domainTemplates = [
  65.             $this->publisherDomain => 'publisher/login/index.html.twig',
  66.             $this->advertiserDomain => 'advertiser/login/index.html.twig',
  67.         ];
  68.         $layoutTemplate $domainTemplates[$domain] ?? 'form_login.html.twig';
  69.         if ($form->isSubmitted() && $form->isValid()) {
  70.             return $this->processSendingPasswordResetEmail(
  71.                 $form->get('email')->getData(),
  72.                 $mailer,
  73.                 $translator,
  74.                 $request
  75.             );
  76.         }
  77.         return $this->render('reset_password/request.html.twig', [
  78.             'requestForm' => $form->createView(),
  79.             'layoutTemplate' => $layoutTemplate,
  80.             'domain' => $domain,
  81.             'publisherDomain' => $this->publisherDomain,
  82.             'advertiserDomain' => $this->advertiserDomain,
  83.         ]);
  84.     }
  85.     /**
  86.      * Confirmation page after a user has requested a password reset.
  87.      *
  88.      * @Route("/check-email", name="app_check_email")
  89.      */
  90.     public function checkEmail(Request $request): Response
  91.     {
  92.         // Get the domain from the request
  93.         $domain $request->getHost();
  94.         // Generate a fake token if the user does not exist or someone hit this page directly.
  95.         // This prevents exposing whether or not a user was found with the given email address or not
  96.         if (null === ($resetToken $this->getTokenObjectFromSession())) {
  97.             $resetToken $this->userResetPasswordHelper->generateFakeResetToken();
  98.         }
  99.         return $this->render('reset_password/check_email.html.twig', [
  100.             'resetToken' => $resetToken,
  101.             'domain' => $domain,
  102.             'publisherDomain' => $this->publisherDomain,
  103.             'advertiserDomain' => $this->advertiserDomain,
  104.         ]);
  105.     }
  106.     /**
  107.      * Validates and process the reset URL that the user clicked in their email.
  108.      *
  109.      * @Route("/reset/{token}", name="app_reset_password")
  110.      */
  111.     public function reset(Request $requestUserPasswordHasherInterface $userPasswordHasherTranslatorInterface $translatorstring $token null): Response
  112.     {
  113.         if ($token) {
  114.             // We store the token in session and remove it from the URL, to avoid the URL being
  115.             // loaded in a browser and potentially leaking the token to 3rd party JavaScript.
  116.             $this->storeTokenInSession($token);
  117.             return $this->redirectToRoute('reset_password_app_reset_password');
  118.         }
  119.         $token $this->getTokenFromSession();
  120.         if (null === $token) {
  121.             throw $this->createNotFoundException('No reset password token found in the URL or in the session.');
  122.         }
  123.         $host $request->getHost();
  124.         $resetPasswordHelpers = [
  125.             $this->publisherDomain => $this->mafoPublisherResetPasswordHelper,
  126.             $this->advertiserDomain => $this->mafoAdvertiserResetPasswordHelper,
  127.             'default' => $this->userResetPasswordHelper,
  128.         ];
  129.         $resetPasswordHelper $resetPasswordHelpers[$host] ?? $resetPasswordHelpers['default'];
  130.         try {
  131.             $user $resetPasswordHelper->validateTokenAndFetchUser($token);
  132.         } catch (ResetPasswordExceptionInterface $e) {
  133.             $this->addFlash('reset_password_error'sprintf(
  134.                 '%s - %s',
  135.                 $translator->trans(ResetPasswordExceptionInterface::MESSAGE_PROBLEM_VALIDATE, [], 'ResetPasswordBundle'),
  136.                 $translator->trans($e->getReason(), [], 'ResetPasswordBundle')
  137.             ));
  138.             return $this->redirectToRoute('reset_password_app_forgot_password_request');
  139.         }
  140.         // The token is valid; allow the user to change their password.
  141.         $form $this->createForm(ChangePasswordFormType::class);
  142.         $form->handleRequest($request);
  143.         if ($form->isSubmitted() && $form->isValid()) {
  144.             // A password reset token should be used only once, remove it.
  145.             $resetPasswordHelper->removeResetRequest($token);
  146.             // Encode(hash) the plain password, and set it.
  147.             $encodedPassword $userPasswordHasher->hashPassword(
  148.                 $user,
  149.                 $form->get('plainPassword')->getData()
  150.             );
  151.             $user->setPassword($encodedPassword);
  152.             $this->entityManager->flush();
  153.             // The session is cleaned up after the password has been changed.
  154.             $this->cleanSessionAfterReset();
  155.             return $this->redirectToRoute('homepage');
  156.         }
  157.         return $this->render('reset_password/reset.html.twig', [
  158.             'resetForm' => $form->createView(),
  159.         ]);
  160.     }
  161.     private function processSendingPasswordResetEmail(string $emailFormDataMailerInterface $mailerTranslatorInterface $translatorRequest $request): RedirectResponse
  162.     {
  163.         //        $user = $this->entityManager->getRepository(Users::class)->findOneBy([
  164.         //            'email' => $emailFormData,
  165.         //        ]);
  166.         // Get the domain of the request
  167.         $domain $request->getHost();
  168.         $entityMapping = [
  169.             $this->publisherDomain => MafoPublisherCabinetManager::class,
  170.             $this->advertiserDomain => MafoAdvertiserCabinetManager::class,
  171.             'default' => Users::class
  172.         ];
  173.         $helperMapping = [
  174.             $this->publisherDomain => $this->mafoPublisherResetPasswordHelper,
  175.             $this->advertiserDomain => $this->mafoAdvertiserResetPasswordHelper,
  176.             'default' => $this->userResetPasswordHelper
  177.         ];
  178.         $entityClass $entityMapping[$domain] ?? $entityMapping['default'];
  179.         $user $this->entityManager->getRepository($entityClass)->findOneBy([
  180.             'email' => $emailFormData,
  181.         ]);
  182.         // Do not reveal whether a user account was found or not.
  183.         if (!$user) {
  184.             return $this->redirectToRoute('reset_password_app_check_email');
  185.         }
  186.         try {
  187.             $resetHelper $helperMapping[$domain] ?? $helperMapping['default'];
  188.             $resetToken $resetHelper->generateResetToken($user);
  189.         } catch (ResetPasswordExceptionInterface $e) {
  190.             // If you want to tell the user why a reset email was not sent, uncomment
  191.             // the lines below and change the redirect to 'reset_password_app_forgot_password_request'.
  192.             // Caution: This may reveal if a user is registered or not.
  193.             //
  194.             // $this->addFlash('reset_password_error', sprintf(
  195.             //     '%s - %s',
  196.             //     $translator->trans(ResetPasswordExceptionInterface::MESSAGE_PROBLEM_HANDLE, [], 'ResetPasswordBundle'),
  197.             //     $translator->trans($e->getReason(), [], 'ResetPasswordBundle')
  198.             // ));
  199.             return $this->redirectToRoute('reset_password_app_check_email');
  200.         }
  201.         $host $request->getSchemeAndHttpHost();
  202.         $email = (new TemplatedEmail())
  203.             ->from(new Address('mafo@mobupps.com''MAFO Password Reset'))
  204.             ->to($user->getEmail())
  205.             ->subject('Your password reset request')
  206.             ->htmlTemplate('reset_password/email.html.twig')
  207.             ->context([
  208.                 'resetToken' => $resetToken,
  209.                 'host' => $host // Pass the host dynamically to the email template
  210.             ]);
  211.         $mailer->send($email);
  212.         // Store the token object in session for retrieval in check-email route.
  213.         $this->setTokenObjectInSession($resetToken);
  214.         return $this->redirectToRoute('reset_password_app_check_email');
  215.     }
  216. }