Skip to content

Instantly share code, notes, and snippets.

@jrushlow
Last active February 23, 2020 20:17
Show Gist options
  • Save jrushlow/59fc19d6558ef67006e2d23881ebac8a to your computer and use it in GitHub Desktop.
Save jrushlow/59fc19d6558ef67006e2d23881ebac8a to your computer and use it in GitHub Desktop.
DO NOT USE - Example of a reset password controller - WIP
<?php
namespace App\Controller;
use ....
/**
* @Route("/forgot-password")
*/
class ForgotPasswordController extends AbstractController
{
use ResetPasswordControllerTrait;
private $resetPasswordHelper;
public function __construct(ResetPasswordHelperInterface $helper)
{
$this->resetPasswordHelper = $helper;
}
/**
* @Route("/request", name="app_forgot_password_request")
*/
public function request(Request $request, MailerInterface $mailer): Response
{
$form = $this->createForm(PasswordRequestFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->processRequestForm($form, $request, $mailer);
}
return $this->render('forgot_password/request.html.twig', [
'requestForm' => $form->createView(),
]);
}
protected function processRequestForm(FormInterface $form, Request $request, MailerInterface $mailer): RedirectResponse
{
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy([
'email' => $form->get('email')->getData(),
]);
// Needed to be able to access next page, app_check_email
$this->setCanCheckEmailInSession();
// Do not reveal whether a user account was found or not.
if (!$user) {
return $this->redirectToRoute('app_check_email');
}
try {
$resetToken = $this->resetPasswordHelper->generateResetToken($user);
} catch (ResetPasswordExceptionInterface $e) {
// TODO - make this better..
$this->addFlash('error', sprintf('Ooops something went wrong. %s', $e->getReason()));
return $this->redirectToRoute('app_forgot_password_request');
}
$email = $this->getEmailTemplate($user->getEmail(), $resetToken);
$mailer->send($email);
return $this->redirectToRoute('app_check_email');
}
protected function getEmailTemplate(string $emailAddress, ResetPasswordToken $resetToken): TemplatedEmail
{
....
}
/**
* @Route("/check-email", name="app_check_email")
*/
public function checkEmail(): Response
{
// We prevent users from directly accessing this page
if (!$this->canCheckEmail()) {
return $this->redirectToRoute('app_forgot_password_request');
}
return $this->render('forgot_password/check_email.html.twig', [
'tokenLifetime' => $this->resetPasswordHelper->getTokenLifetime(),
]);
}
/**
* @Route("/reset/{token}", name="app_reset_password")
*/
public function reset(Request $request, UserPasswordEncoderInterface $passwordEncoder, string $token = null): Response
{
//Put token in session and redirect to self
if ($token) {
// We store token in session and remove it from the URL,
// to avoid any leak if someone get to know the URL (AJAX requests, Analytics...).
$this->storeTokenInSession(string $token);
return $this->redirectToRoute('app_reset_password');
}
//Get token out of session storage
$token = $this->getTokenFromSession();
if (!$token) {
throw $this->createNotFoundException();
}
//Validate token using password helper
$user = $this->resetPasswordHelper->validateTokenAndFetchUser($token);
//Reset password after token verified
//@TODO Move to separate method
$form = $this->createForm(PasswordResettingFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// A ResetPasswordToken should be used only once, remove it.
$this->resetPasswordHelper->removeResetRequest($token);
$this->cleanSessionAfterReset();
// Encode the plain password, and set it.
$encodedPassword = $passwordEncoder->encodePassword(
$user,
$form->get('plainPassword')->getData()
);
$user->setPassword($encodedPassword);
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('app_forgot_password_request');
}
return $this->render('forgot_password/reset.html.twig', [
'resetForm' => $form->createView(),
]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment