<?php
namespace App\Controller;
use App\Form\ForgotPasswordType;
use App\Form\ResetPasswordType;
use App\Repository\UserRepository;
use App\Service\ResetPasswordService;
use App\Service\UserNotificationService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
class ResetPasswordController extends AbstractController
{
private $entityManager;
private $userRepository;
private $resetPasswordService;
private $notificationService;
private $passwordHasher;
public function __construct(
EntityManagerInterface $entityManager,
UserRepository $userRepository,
ResetPasswordService $resetPasswordService,
UserNotificationService $notificationService,
UserPasswordHasherInterface $passwordHasher
) {
$this->entityManager = $entityManager;
$this->userRepository = $userRepository;
$this->resetPasswordService = $resetPasswordService;
$this->notificationService = $notificationService;
$this->passwordHasher = $passwordHasher;
}
/**
* @Route("/forgot-password", name="app_forgot_password")
*/
public function request(Request $request): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('app_dashboard');
}
$form = $this->createForm(ForgotPasswordType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$email = $form->get('email')->getData();
$user = $this->userRepository->findByEmail($email);
if ($user && $user->getIsActive()) {
// Créer le token de réinitialisation
$resetToken = $this->resetPasswordService->createResetToken($user);
// Envoyer l'email
$this->notificationService->sendResetPasswordEmail($user, $resetToken->getToken());
}
// Toujours rediriger vers la page de confirmation pour éviter l'énumération des utilisateurs
return $this->render('security/forgot_password_check_email.html.twig');
}
return $this->render('security/forgot_password.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/reset-password/{token}", name="app_reset_password")
*/
public function reset(string $token, Request $request): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('app_dashboard');
}
$resetToken = $this->resetPasswordService->validateToken($token);
if (!$resetToken) {
$this->addFlash('error', 'Ce lien de réinitialisation est invalide ou a expiré. Veuillez faire une nouvelle demande.');
return $this->redirectToRoute('app_forgot_password');
}
$form = $this->createForm(ResetPasswordType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$newPassword = $form->get('newPassword')->getData();
$user = $resetToken->getUser();
// Hasher et enregistrer le nouveau mot de passe
$hashedPassword = $this->passwordHasher->hashPassword($user, $newPassword);
$user->setPassword($hashedPassword);
$user->setMustChangePassword(false);
// Marquer le token comme utilisé
$this->resetPasswordService->markTokenAsUsed($resetToken);
$this->entityManager->flush();
// Envoyer un email de confirmation
$this->notificationService->sendPasswordChangedNotification($user);
$this->addFlash('success', 'Votre mot de passe a été réinitialisé avec succès ! Vous pouvez maintenant vous connecter.');
return $this->redirectToRoute('app_login');
}
return $this->render('security/reset_password.html.twig', [
'form' => $form->createView(),
'token' => $token,
]);
}
}