src/Controller/ResetPasswordController.php line 67

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