src/Controller/ResetPasswordController.php line 52

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * ImmoBay - BAUR Immobilien
  5.  *
  6.  * @copyright  Copyright (c) 2008-2022, 47GradNord - Agentur für Internetlösungen
  7.  * @author     47GradNord - Agentur für Internetlösungen <info@47gradnord.de>
  8.  */
  9. namespace App\Controller;
  10. use App\Entity\User;
  11. use App\Form\ChangePasswordFormType;
  12. use App\Form\ResetPasswordRequestFormType;
  13. use Doctrine\ORM\EntityManagerInterface;
  14. use http\Exception;
  15. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  16. use Symfony\Component\HttpFoundation\RedirectResponse;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Symfony\Component\HttpFoundation\Response;
  19. use Symfony\Component\Mailer\MailerInterface;
  20. use Symfony\Component\Mime\Address;
  21. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  22. use Symfony\Component\Routing\Annotation\Route;
  23. use SymfonyCasts\Bundle\ResetPassword\Controller\ResetPasswordControllerTrait;
  24. use SymfonyCasts\Bundle\ResetPassword\Exception\ResetPasswordExceptionInterface;
  25. use SymfonyCasts\Bundle\ResetPassword\ResetPasswordHelperInterface;
  26. /**
  27.  * @Route("/reset-password")
  28.  */
  29. class ResetPasswordController extends AbstractAppController
  30. {
  31.     use ResetPasswordControllerTrait;
  32.     private $resetPasswordHelper;
  33.     private $entityManager;
  34.     public function __construct(ResetPasswordHelperInterface $resetPasswordHelperEntityManagerInterface $entityManager)
  35.     {
  36.         $this->resetPasswordHelper $resetPasswordHelper;
  37.         $this->entityManager $entityManager;
  38.     }
  39.     /**
  40.      * Display & process form to request a password reset.
  41.      *
  42.      * @Route("", name="app_forgot_password_request")
  43.      */
  44.     public function request(Request $requestMailerInterface $mailer): Response
  45.     {
  46.         $form $this->createForm(ResetPasswordRequestFormType::class);
  47.         $form->handleRequest($request);
  48.         if ($form->isSubmitted() && $form->isValid()) {
  49.             return $this->processSendingPasswordResetEmail(
  50.                 $form->get('email')->getData(),
  51.                 $mailer
  52.             );
  53.         }
  54.         return $this->render('reset_password/request.html.twig', [
  55.             'requestForm' => $form->createView(),
  56.         ]);
  57.     }
  58.     /**
  59.      * Confirmation page after a user has requested a password reset.
  60.      *
  61.      * @Route("/check-email", name="app_check_email")
  62.      */
  63.     public function checkEmail(): Response
  64.     {
  65.         // Generate a fake token if the user does not exist or someone hit this page directly.
  66.         // This prevents exposing whether or not a user was found with the given email address or not
  67.         if (null === ($resetToken $this->getTokenObjectFromSession())) {
  68.             $resetToken $this->resetPasswordHelper->generateFakeResetToken();
  69.         }
  70.         return $this->render('reset_password/check_email.html.twig', [
  71.             'resetToken' => $resetToken,
  72.         ]);
  73.     }
  74.     /**
  75.      * Validates and process the reset URL that the user clicked in their email.
  76.      *
  77.      * @Route("/reset/{token}", name="app_reset_password")
  78.      */
  79.     public function reset(Request $requestUserPasswordHasherInterface $userPasswordHasherstring $token null): Response
  80.     {
  81.         if ($token) {
  82.             // We store the token in session and remove it from the URL, to avoid the URL being
  83.             // loaded in a browser and potentially leaking the token to 3rd party JavaScript.
  84.             $this->storeTokenInSession($token);
  85.             return $this->redirectToRoute('app_reset_password');
  86.         }
  87.         $token $this->getTokenFromSession();
  88.         if (null === $token) {
  89.             throw $this->createNotFoundException('No reset password token found in the URL or in the session.');
  90.         }
  91.         try {
  92.             $user $this->resetPasswordHelper->validateTokenAndFetchUser($token);
  93.         } catch (ResetPasswordExceptionInterface $e) {
  94.             $this->addFlash('reset_password_error'sprintf(
  95.                 'There was a problem validating your reset request - %s',
  96.                 $e->getReason()
  97.             ));
  98.             return $this->redirectToRoute('app_forgot_password_request');
  99.         }
  100.         // The token is valid; allow the user to change their password.
  101.         $form $this->createForm(ChangePasswordFormType::class);
  102.         $form->handleRequest($request);
  103.         if ($form->isSubmitted() && $form->isValid()) {
  104.             // A password reset token should be used only once, remove it.
  105.             $this->resetPasswordHelper->removeResetRequest($token);
  106.             // Encode(hash) the plain password, and set it.
  107.             $encodedPassword $userPasswordHasher->hashPassword(
  108.                 $user,
  109.                 $form->get('plainPassword')->getData()
  110.             );
  111.             $user->setPassword($encodedPassword);
  112.             $this->entityManager->flush();
  113.             // The session is cleaned up after the password has been changed.
  114.             $this->cleanSessionAfterReset();
  115.             return $this->redirectToRoute('app_index');
  116.         }
  117.         return $this->render('reset_password/reset.html.twig', [
  118.             'resetForm' => $form->createView(),
  119.         ]);
  120.     }
  121.     /**
  122.      * @Route("/changepassword-forced", name="app_changepassword_forced")
  123.      */
  124.     public function changePasswordForced(Request $requestUserPasswordHasherInterface $userPasswordHasher): Response
  125.     {
  126.         /** @var User $user */
  127.         $user $this->getUser();
  128.         if (null === $user) {
  129.             throw $this->createAccessDeniedException('Diese Seite ist nicht aufrufbar');
  130.         }
  131.         $form $this->createForm(ChangePasswordFormType::class, $user);
  132.         $form->handleRequest($request);
  133.         if ($form->isSubmitted() && $form->isValid()) {
  134.             try {
  135.                 $changePassword $request->request->get('change_password_form');
  136.                 $password $changePassword['plainPassword']['first'];
  137.                 $pass $userPasswordHasher->hashPassword($user$password);
  138.                 $user->setPassword($pass);
  139.                 // $user->setForceChangePassword(false);
  140.                 $this->entityManager->persist($user);
  141.                 $this->entityManager->flush();
  142.                 $this->addFlash('success''Password erfolgreich geändert!');
  143.             } catch (Exception $e) {
  144.                 $this->addFlash('danger''Fehler, bitte versuchen Sie es erneut.');
  145.                 return $this->redirectToRoute('app_changepassword_forced');
  146.             }
  147.             return $this->redirectToRoute('app_logout');
  148.         }
  149.         return $this->render('reset_password/reset.html.twig', [
  150.             'resetForm' => $form->createView(),
  151.             'user' => $this->getUser(),
  152.         ]);
  153.     }
  154.     private function processSendingPasswordResetEmail(string $emailFormDataMailerInterface $mailer): RedirectResponse
  155.     {
  156.         $user $this->entityManager->getRepository(User::class)->findOneBy([
  157.             'email' => $emailFormData,
  158.         ]);
  159.         // Do not reveal whether a user account was found or not.
  160.         if (!$user) {
  161.             return $this->redirectToRoute('app_check_email');
  162.         }
  163.         try {
  164.             $resetToken $this->resetPasswordHelper->generateResetToken($user);
  165.         } catch (ResetPasswordExceptionInterface $e) {
  166.             // If you want to tell the user why a reset email was not sent, uncomment
  167.             // the lines below and change the redirect to 'app_forgot_password_request'.
  168.             // Caution: This may reveal if a user is registered or not.
  169.             //
  170.             // $this->addFlash('reset_password_error', sprintf(
  171.             //     'There was a problem handling your password reset request - %s',
  172.             //     $e->getReason()
  173.             // ));
  174.             return $this->redirectToRoute('app_check_email');
  175.         }
  176.         $email = (new TemplatedEmail())
  177.             ->from(new Address('no-reply@baur-immobilien.de''Bieter-Plattform | BAUR-Immobilien'))
  178.             ->to($user->getEmail())
  179.             ->subject('Ihre Anfrage: Passwort zurücksetzen')
  180.             ->htmlTemplate('reset_password/email.html.twig')
  181.             ->context([
  182.                 'resetToken' => $resetToken,
  183.             ]);
  184.         $mailer->send($email);
  185.         // Store the token object in session for retrieval in check-email route.
  186.         $this->setTokenObjectInSession($resetToken);
  187.         return $this->redirectToRoute('app_check_email');
  188.     }
  189. }