<?php
namespace App\Controller\Security;
use App\Form\ForgotPasswordType;
use App\Form\ResetPasswordFormType;
use App\Repository\ClientRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Uid\Uuid;
class ForgotPasswordController extends AbstractController
{
private RouterInterface $router;
private RequestStack $requestStack;
public function __construct(
ClientRepository $clientRepository,
RouterInterface $router,
RequestStack $requestStack,
EntityManagerInterface $entityManager
)
{
$this->clientRepository = $clientRepository;
$this->router = $router;
$this->requestStack = $requestStack;
$this->entityManager = $entityManager;
}
/**
* @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
*/
#[Route('/mot-de-passe-oublie', name: 'app_forgot_password')]
public function request(Request $request, MailerInterface $mailer): Response
{
$form = $this->createForm(ForgotPasswordType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$email = $form->get('email')->getData();
$client = $this->clientRepository->findOneBy(['email' => $email]);
if ($client) {
// Générer un token unique
$resetToken = Uuid::v4()->toRfc4122();
$client->setResetToken($resetToken);
$client->setResetTokenExpiresAt(new \DateTime('+1 hour'));
$this->entityManager->flush();
// Récupérer la requête courante pour extraire le port
$request = $this->requestStack->getCurrentRequest();
$host = $request->getHost();
$scheme = $request->getScheme();
$port = $request->getPort();
// Générer l'URL absolue avec le bon token
$resetUrl = $this->router->generate(
'app_reset_password',
['token' => $resetToken], // Utiliser le token généré
UrlGeneratorInterface::ABSOLUTE_URL
);
// Ajouter le port uniquement si nécessaire
if ($port && strpos($resetUrl, ":$port") === false) {
$resetUrl = preg_replace("/^($scheme:\/\/$host)/", "$1:$port", $resetUrl);
}
$email = (new Email())
->from('contact@panda-coworking.com') // Adresse expéditeur
->to($client->getEmail()) // Adresse du client (destinataire)
->subject('Réinitialisation de votre mot de passe') // Sujet
->html( // Contenu HTML
"<p>Bonjour,</p>
<p>Cliquez sur le lien suivant pour réinitialiser votre mot de passe :</p>
<a href='$resetUrl'>$resetUrl</a>"
);
// Envoi de l'email
try {
$mailer->send($email);
} catch (\Exception $e) {
return new Response('Échec de l\'envoi de l\'e-mail : ' . $e->getMessage());
}
// Message de succès
$this->addFlash('success', 'Un email a été envoyé pour réinitialiser votre mot de passe.');
}
return $this->redirectToRoute('app_forgot_password');
}
return $this->render('security/forgot_password.html.twig', [
'form' => $form->createView(),
'path_name'=>'app_forgot_password',
]);
}
#[Route('/reinitialisation-mot-de-passe/{token}', name: 'app_reset_password')]
public function reset(Request $request, string $token): Response
{
// Récupérer le client via le token
$client = $this->clientRepository->findOneBy(['resetToken' => $token]);
if (!$client || $client->getResetTokenExpiresAt() < new \DateTime()) {
// Gérer l'erreur si le token est invalide ou expiré
return $this->redirectToRoute('app_forgot_password');
}
// Créer et gérer le formulaire de réinitialisation du mot de passe
$form = $this->createForm(ResetPasswordFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// Récupérer le nouveau mot de passe
$newPassword = $form->get('password')->getData();
// Hacher le mot de passe avec password_hash()
$hashedPassword = password_hash($newPassword, PASSWORD_BCRYPT);
$client->setPassword($hashedPassword);
$client->setResetToken(null); // Réinitialiser le token
// Sauvegarder le client avec son nouveau mot de passe
$this->entityManager->flush();
// Ajouter un message flash et rediriger
$this->addFlash('success', 'Votre mot de passe a été réinitialisé avec succès.');
return $this->redirectToRoute('login');
}
return $this->render('security/reset_password.html.twig', [
'form' => $form->createView(),
'path_name' => 'app_reset_password'
]);
}
}