<?php
namespace App\Controller\Common;
use App\Entity\Doctrine\App\User;
use App\Entity\Doctrine\App\ValidationToken;
use App\Exception\UnauthorisedPasswordChangeException;
use App\Exception\UserPersonalInfosNotFoundException;
use App\Form\ForgottenPassword\MailOrPhoneType;
use App\Form\ForgottenPassword\PasswordType;
use App\Manager\ForgottenPasswordManager;
use App\Manager\ValidationTokenManager;
use App\Repository\UserRepositoryInterface;
use Doctrine\DBAL\Exception;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\ORMException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* Class ForgottenPasswordController
* @package App\Controller\Frontend
* @Route(path="/forgotten-password", name="forgotten_password.")
*/
class ForgottenPasswordController extends AbstractController
{
/**
* @Route(path="/send-token", name="send_token")
* @param Request $request
* @param ValidationTokenManager $validationTokenManager
* @param ForgottenPasswordManager $forgottenPasswordManager
* @return Response
* @throws NonUniqueResultException
* @throws Exception
* @throws ORMException
*/
public function sendToken(
Request $request,
ValidationTokenManager $validationTokenManager,
ForgottenPasswordManager $forgottenPasswordManager
): Response {
$form = $this->createForm(MailOrPhoneType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$value = $form->get('value')->getData();
try {
$validationToken = $forgottenPasswordManager->execute($value);
} catch (UserPersonalInfosNotFoundException | UnauthorisedPasswordChangeException $e) {
$this->addFlash('error', $e->getMessage());
return $this->redirectToRoute('app.forgotten_password.send_token');
}
$validationTokenManager->create($validationToken);
return $this->redirectToRoute('app.validation.token', [
'username' => $validationToken->getUser()->getUsername(),
'property' => $validationToken->getProperty()
]);
}
return $this->render('frontend/forgotten_password/send_token.html.twig', [
'form' => $form->createView()
]);
}
/**
* @Route(path="/reset/{username}/{token}", name="reset")
* @param string $username
* @param string $token
* @param Request $request
* @param UserRepositoryInterface $userRepository
* @param EntityManagerInterface $em
* @return RedirectResponse|Response
*/
public function reset(
string $username,
string $token,
Request $request,
UserRepositoryInterface $userRepository,
EntityManagerInterface $em
) {
$user = $em->getRepository(User::class)->findOneBy(['username' => $username]);
$validationToken = $em->getRepository(ValidationToken::class)->findOneBy([
'user' => $user,
'property' => ValidationToken::PROPERTY_PASSWORD,
'token' => $token
]);
if (!$validationToken instanceof ValidationToken) {
$this->addFlash('error', 'Le code n\'est pas valide');
return $this->redirectToRoute('app.validation.token', [
'username' => $user->getUsername(),
'property' => ValidationToken::PROPERTY_PASSWORD
]);
}
if ($validationToken->getExpiration() < new \DateTime()) {
$this->addFlash('error', 'Le code a expiré veuillez recommencer la procédure depuis le début');
return $this->redirectToRoute('app.validation.token', [
'username' => $username,
'property' => ValidationToken::PROPERTY_PASSWORD
]);
}
$form = $this->createForm(PasswordType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$newPassword = $form->get('newPassword')->getData();
// Update password
$user = $userRepository->findByUsername($user->getUsername());
if (!$userRepository->updatePassword($user, $newPassword)) {
$this->addFlash('error', 'Votre mot de passe n\'a pas pu être modifié');
} else {
$this->addFlash('success', 'Votre mot de passe a été modifié avec succès');
}
return $this->redirectToRoute('app.login');
}
return $this->render('frontend/forgotten_password/reset_password.html.twig', [
'form' => $form->createView()
]);
}
}