<?php
namespace App\Controller;
use Datetime;
//use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use App\Entity\User;
use App\Services\Mailer;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use App\Form\ResettingType;
use App\Security\TokenAuthenticator;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
/**
* @Route("/renouvellement-mot-de-passe")
*/
class ResettingController extends AbstractController
{
public function __construct()
{
$dotenv = new Dotenv();
$dotenv->load(__DIR__ . '/../../.env');
}
/**
* @Route("/", name="request_resetting")
* @param Request $request
* @param Mailer $mailer
* @param TokenGeneratorInterface $tokenGenerator
* @return RedirectResponse|Response
* @throws TransportExceptionInterface
*/
public function request(Request $request, Mailer $mailer, TokenGeneratorInterface $tokenGenerator)
{
// création d'un formulaire "à la volée", afin que l'internaute puisse renseigner son mail
$email = $request->get("email");
$form = $this->createFormBuilder()
->add('email', EmailType::class, [
'attr'=>['placeholder'=>'Email'],
'label' => false,
'constraints' => [
new Email(),
new NotBlank()
], "data"=>$email
])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository(User::class)->loadUserByEmail($form->getData()['email']);
// aucun email associé à ce compte.
if (!$user) {
$request->getSession()->getFlashBag()->add('warning', "Cet email n'existe pas.");
return $this->redirectToRoute("request_resetting");
}
// création du token
$user->setToken($tokenGenerator->generateToken());
// enregistrement de la date de création du token
$user->setPasswordRequestedAt(new Datetime());
$em->flush();
// on utilise le service Mailer créé précédemment
// $bodyMail = $mailer->createBodyMail('auth/mail.html.twig', [
// 'user' => $user
// ]);
// $mailer->sendMessage('from@email.com', $user->getEmail(), 'renouvellement du mot de passe', $bodyMail);
// $request->getSession()->getFlashBag()->add('success', "Un mail va vous être envoyé afin que vous puissiez renouveller votre mot de passe. Le lien que vous recevrez sera valide 24h.");
$datasJson = [];
$datasJson["user"]["email"] = $user->getEmail();
$datasJson["user"]["vendor"] = $user->getShopifyVendorName();
$datasJson["user"]["url"] = $this->generateUrl('resetting', ['id' => $user->getId(), 'token' => $user->getToken()], UrlGeneratorInterface::ABSOLUTE_URL);
$client = HttpClient::create();
$configs = ['headers' => ["Content-Type" => "application/json"]];
$configs['body'] = json_encode($datasJson);
$client->request('POST', $_ENV['ZAPIER_MAIL_MDP'], $configs);
/* penser a faire un log ???
$res= $client->request('POST', $_ENV['ZAPIER_MAIL_MDP'], $configs);
var_dump($res->getContent());exit(); */
return $this->redirectToRoute("app_login");
}
return $this->render('auth/reset.html.twig', [
'form' => $form->createView()
]);
}
/**
* si supérieur à 10min, retourne false
* sinon retourne false
* @param Datetime|null $passwordRequestedAt
* @return bool
*/
public static function isRequestInTime(Datetime $passwordRequestedAt = null): bool
{
if ($passwordRequestedAt === null) {
return false;
}
$now = new DateTime();
$interval = $now->getTimestamp() - $passwordRequestedAt->getTimestamp();
// $daySeconds = 60 * 10;
//$daySeconds = 3600 * 24 ; //pour 24h
$daySeconds = 3600 * 24 * 365; //pour 1 AN
$response = $interval > $daySeconds ? false : true;
return $response;
}
/**
* @Route("/{id}/{token}", name="resetting")
* @param User $user
* @param $token
* @param Request $request
* @param UserPasswordEncoderInterface $passwordEncoder
* @return RedirectResponse|Response
*/
public function resetting(User $user, $token, Request $request, UserPasswordEncoderInterface $passwordEncoder)
{
// interdit l'accès à la page si:
// le token associé au membre est null
// le token enregistré en base et le token présent dans l'url ne sont pas égaux
// le token date de plus de 10 minutes
if ($user->getToken() === null || $token !== $user->getToken() || !self::isRequestInTime($user->getPasswordRequestedAt())) {
// throw new AccessDeniedHttpException();
return $this->redirectToRoute('app_login');
}
$form = $this->createForm(ResettingType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
// réinitialisation du token à null pour qu'il ne soit plus réutilisable
$user->setToken(null);
$user->setPasswordRequestedAt(null);
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$request->getSession()->getFlashBag()->add('success', "Votre mot de passe a été renouvelé.");
return $this->redirectToRoute('app_login');
}
return $this->render('auth/change.html.twig', [
'form' => $form->createView(),
'user'=>$user
]);
}
}