<?php
namespace App\Controller;
use App\Entity\User;
use App\Form\ForgotType;
use App\Form\ForgotPassType;
use App\Repository\UserRepository;
use Symfony\Component\Mime\Address;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class SecurityController extends AbstractController
{
private $params;
public function __construct(ParameterBagInterface $params)
{
$this->params = $params;
}
/**
* @Route("/login", name="app_login")
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('app_home_page');
}
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/logout", name="app_logout")
*/
public function logout(): void
{
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
/**
* @Route("/forgot-password", name="app_forgot_password")
*/
public function forgot(): Response
{
$form = $this->createForm(ForgotType::class,[
'action' => $this->generateUrl('app_forgot_pass_submit'),
'method' => 'POST',
'id' => 'test'
]);
return $this->render('security/forgotPassword.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/forgot-password-submit", name="app_forgot_pass_submit", methods={"POST"})
*/
public function forgotSubmit(Request $request, UserRepository $userRepository, MailerInterface $mailer,EntityManagerInterface $entityManager)
{
$data = $request->request->get('forgot');
$status = "error";
$message = "";
$title = "Mot de passe oublié";
if ($data) {
$email = $data["email"];
// vérifier si c'est un email valid en PHP
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$message = "Format email invalid";
} else {
// récupération de l'utilisateur contenant l'email
$user = $userRepository->findOneBy(['email' => $email]);
if ($user instanceof User) {
$now = new \DateTime();
// dd($now,$this->params);
$string = $this->params->get("encryption.salt.reset_password").$now->format("YmdHim")."_".$user->getId();
$key = urlencode(base64_encode($string));
// Envoi mail si pas d'erreur
$toAddresses = [new Address($user->getEmail())];
$email = (new TemplatedEmail())
->to(...$toAddresses)
->subject('Mot de passe oublié')
// path of the Twig template to render
->htmlTemplate('mailer/change_password.html.twig')
// pass variables (name => value) to the template
->context([
'now' => $now,
'username' => $user->getFirstname(),
'key' => $key
]);
$user->setDateSendResetPassword($now);
$entityManager->persist($user);
$entityManager->flush();
try {
$mailer->send($email);
// mise à jour date reset password
$user->setDateSendResetPassword($now);
$entityManager->persist($user);
$entityManager->flush();
$status = "success";
$message = "Veuillez vérifier votre email pour modifier votre mot de passe";
} catch (TransportExceptionInterface $e) {
$status = "error";
$message = "Envoi mail echoué, verifiez votre connexion";
// throw new Exception($e, 1);
}
} else {
$message = "Email utilisateur non trouvé dans la base";
}
}
} else {
$message = "Aucune données posté par la méthode";
}
// return new JsonResponse(
// [
// 'title' => $title,
// 'message' => $message,
// 'status' => $status,
// ],
// 200,
// ['Content-Type' => 'application/json']
// );
return $this->render('mailer/page.html.twig',[
'title' => $title,
'message' => $message,
'status' => $status
]);
}
/**
* @Route("/forgot-send-url/{key}", name="app_forgot_send_url")
*/
public function forgotSendUrl(String $key, UserRepository $userRepository)
{
// decodé l'URL
$string = base64_decode(urldecode($key));
// enlever le SALT de l(URL)
$string = str_ireplace($this->params->get("encryption.salt.reset_password"), "", $string);
// récupérer la date et l'ID de l'utilisateur
$string = explode("_", $string);
$dateUrl = $string[0];
$user_id = (int)$string[1];
$user = $userRepository->find($user_id);
if($user instanceof User && !empty($user->getDateSendResetPassword())) {
$dateUrlUser = $user->getDateSendResetPassword();
$dateUrlUser = $dateUrlUser->format("YmdHim");
if($dateUrl == $dateUrlUser){
$form = $this->createForm(ForgotPassType::class, $user, [
'action' => $this->generateUrl('app_forgot_send_url_submit'),
'method' => 'POST'
]);
return $this->render('security/forgotPassForm.html.twig', [
'form' => $form->createView(),
'id' => $user->getId(),
]);
}
else{
throw $this->createNotFoundException('Lien expiré teou inexistant');
}
}
else{
throw $this->createNotFoundException('Lien expiré ou inexistant');
}
}
/**
* @Route("/forgot-send-url-submit", name="app_forgot_send_url_submit", methods={"POST"})
*/
public function forgotSendUrlSubmit(Request $request, UserRepository $userRepository, MailerInterface $mailer, UserPasswordEncoderInterface $passwordEncoder,EntityManagerInterface $entityManager)
{
$data = $request->request->get('forgot_pass');
$user_id = (int)$request->request->get('user_id');
$status = "error";
$message = "";
if ($data) {
$user = $userRepository->find($user_id);
if($user instanceof User){
$email = $user->getEmail();
// vérifier si c'est un email valid en PHP
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$message = "Format email invalid";
} else {
// récupération de l'utilisateur contenant l'email
$user = $userRepository->findOneBy(['email' => $email]);
if ($user instanceof User) {
$string1 = $data["password"]["first"];
$string2 = $data["password"]["second"];
// On vérifie si c'est le même mot de passe
if ($string1 == $string2) {
// Envoi mail si pas d'erreur
$toAddresses = [new Address($user->getEmail())];
$email = (new TemplatedEmail())
->to(...$toAddresses)
->subject('Mot de passe oublié')
// path of the Twig template to render
->htmlTemplate('mailer/send_password.html.twig')
// pass variables (name => value) to the template
->context([
'now' => new \DateTime(),
'username' => $user->getFirstname(),
'random_string' => $string1
]);
try {
$mailer->send($email);
} catch (TransportExceptionInterface $e) {
// throw new Exception($e, 1);
}
// encode the plain password
$user->setPassword(
$passwordEncoder->encodePassword(
$user,
$string1
)
);
// mot de passe oublié permettant de désactiver l'URL dans le mail
$user->setDateSendResetPassword(null);
$entityManager->persist($user);
$entityManager->flush();
$status = "success";
$message = "Enregistrement effectué avec succès, veuillez vérifier votre email";
} else {
$message = "Mot de passe incorrecte";
}
} else {
$message = "Email utilisateur non trouvé dans la base";
}
}
}
else{
$message = "Utilisateur inexistant ou non reconnu par l'application";
}
} else {
$message = "Aucune données posté par la méthode";
}
return $this->redirectToRoute('app_login');
}
}