<?php
// src/Controller/SecurityController.php
namespace App\UserBundle\Controller;
use App\Controller\Traits\GenericTrait;
use App\Entity\User;
use App\UserBundle\Events\ResettingPasswordEvent;
use App\UserBundle\Form\ResettingType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Contracts\Service\Attribute\Required;
use Symfony\Contracts\Translation\TranslatorInterface;
class ResettingController extends AbstractController
{
use GenericTrait;
#[Required]
public EventDispatcherInterface $eventDispatcher;
#[Route("/request", name: "resetting_request")]
public function request(
Request $request,
EntityManagerInterface $em,
TranslatorInterface $translator
): Response
{
$session = new Session();
if($request->getMethod() == 'POST'){
$username = $request->request->get('_username');
$user = $em->getRepository(User::class)->findUserByUsernameOrEmail($username);
if(!empty($user) && $user instanceof User){
/**
* @var User $user
*/
if($user->getPasswordRequestedAt() !== null){
if($user->getPasswordRequestedAt()->getTimestamp() + $this->getParameter('retry_ttl') > time()){
$session->getFlashBag()->add('warning', $translator->trans('resetting.ttl_not_reached',['%duration%' => $this->getParameter('retry_ttl')],'userbundle'));
return $this->redirectToRoute('resetting_request');
}
}
$user->setPasswordRequestedAt(new \DateTime('now'));
$token = md5(random_bytes(100));
$user->setConfirmationToken($token);
$em->persist($user);
$em->flush();
$event = new ResettingPasswordEvent($user);
$this->eventDispatcher->dispatch($event);
$session->getFlashBag()->add('success', $translator->trans('resetting.request.success',[],'userbundle'));
} else {
$session->getFlashBag()->add('warning', $translator->trans('resetting.request.failed',[],'userbundle'));
}
return $this->redirectToRoute('resetting_request');
}
return $this->render('@UserBundle/Resetting/request.html.twig');
}
#[Route("/resetting/{token}",name: 'resetting_action')]
public function resetPassword(
Request $request,
UserPasswordHasherInterface $userPasswordEncoder,
EntityManagerInterface $em,
TranslatorInterface $translator,
string $token
): Response
{
$session = new Session();
$user = $em->getRepository(User::class)->findOneBy(['confirmation_token' => $token]);
if(empty($user)){
$session->getFlashBag()->add('danger', $translator->trans('resetting.token.error',[],'userbundle'));
return $this->redirectToRoute('resetting_request');
}
$form = $this->createForm(ResettingType::class,null);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$encodedPassword = $userPasswordEncoder->hashPassword($user, $form->get('password')->getData());
$user->setPassword($encodedPassword);
$user->setConfirmationToken(null);
$user->setPasswordRequestedAt(null);
$em->persist($user);
$em->flush();
$session->getFlashBag()->add('success', $translator->trans('resetting.success',[],'userbundle'));
return $this->redirectToRoute('app_login');
}
return $this->render('@User/Resetting/reset.html.twig', ['form' => $form->createView()]);
}
}