Comments (6)
Sure! Contributions are always welcome! But first, I would suggest reading Symfony's Contributing Guide.
Second, let's make sure you're in the right repository. Using a simple project as an example, any files that are in vendor/symfonycasts/reset-password-bundle
belong to the SymfonyCasts/reset-password-bundle
Github Repository (The one you're in now).
Any files that were created as a result of bin/console make:reset-password
- Symfony's Maker Bundle is responsible for those. E.,g. src/Controller/ResetPasswordController.php
or tempates/reset_password/check_email.html.twig
.
Having said that, if you have some code you are unsure which repository it belongs in, feel free to post it below and I'll do my best to get you moving in the right direction.
from reset-password-bundle.
OK thanks for your answer. I pasted my modified controller below, I deleted a method and modified some lines. Compare my controller and tell me what you think. Less code, same use, 1 file view less.
<?php
namespace App\Controller;
use App\Entity\User;
use App\Form\ChangePasswordFormType;
use App\Form\ResetPasswordRequestFormType;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use SymfonyCasts\Bundle\ResetPassword\Controller\ResetPasswordControllerTrait;
use SymfonyCasts\Bundle\ResetPassword\Exception\ResetPasswordExceptionInterface;
use SymfonyCasts\Bundle\ResetPassword\ResetPasswordHelperInterface;
/**
* @Route("/reset-password")
*/
class ResetPasswordController extends AbstractController
{
use ResetPasswordControllerTrait;
private $resetPasswordHelper;
public function __construct(ResetPasswordHelperInterface $resetPasswordHelper)
{
$this->resetPasswordHelper = $resetPasswordHelper;
}
/**
* Display & process form to request a password reset.
*
* @Route("", name="app_forgot_password_request")
*/
public function request(Request $request, MailerInterface $mailer): Response
{
$form = $this->createForm(ResetPasswordRequestFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->processSendingPasswordResetEmail(
$form->get('email')->getData(),
$mailer
);
}
return $this->render('reset_password/request.html.twig', [
'requestForm' => $form->createView(),
]);
}
/**
* Validates and process the reset URL that the user clicked in their email.
*
* @Route("/reset/{token}", name="app_reset_password")
*/
public function reset(Request $request, UserPasswordEncoderInterface $passwordEncoder, string $token = null): Response
{
if ($token) {
// We store the token in session and remove it from the URL, to avoid the URL being
// loaded in a browser and potentially leaking the token to 3rd party JavaScript.
$this->storeTokenInSession($token);
return $this->redirectToRoute('app_reset_password');
}
$token = $this->getTokenFromSession();
if (null === $token) {
throw $this->createNotFoundException('No reset password token found in the URL or in the session.');
}
try {
$user = $this->resetPasswordHelper->validateTokenAndFetchUser($token);
} catch (ResetPasswordExceptionInterface $e) {
$this->addFlash('danger', sprintf(
'Un problème est survenu lors de votre demande de réinitialisation - %s',
$e->getReason()
));
return $this->redirectToRoute('app_forgot_password_request');
}
// The token is valid; allow the user to change their password.
$form = $this->createForm(ChangePasswordFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// A password reset token should be used only once, remove it.
$this->resetPasswordHelper->removeResetRequest($token);
// Encode the plain password, and set it.
$encodedPassword = $passwordEncoder->encodePassword(
$user,
$form->get('plainPassword')->getData()
);
$user->setPassword($encodedPassword);
$this->getDoctrine()->getManager()->flush();
// The session is cleaned up after the password has been changed.
$this->cleanSessionAfterReset();
$this->addFlash(
'success',
'Votre mot de passe vient d\'être réinitialisé avec succés.'
);
return $this->redirectToRoute('app_login');
}
return $this->render('reset_password/reset.html.twig', [
'resetForm' => $form->createView(),
]);
}
private function processSendingPasswordResetEmail(string $emailFormData, MailerInterface $mailer): RedirectResponse
{
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy([
'email' => $emailFormData,
]);
// Marks that you are allowed to see the app_check_email page.
$this->setCanCheckEmailInSession(); // now I think this line is useless ?
// Do not reveal whether a user account was found or not.
if ($user) { // change: a user is found then we enter the condition.
try {
$resetToken = $this->resetPasswordHelper->generateResetToken($user);
} catch (ResetPasswordExceptionInterface $e) {
$this->addFlash('danger', sprintf(
'There was a problem handling your password reset request - %s',
$e->getReason()
));
return $this->redirectToRoute('app_forgot_password_request');
}
$email = (new TemplatedEmail())
->from(new Address('[email protected]', 'Acme Mail Bot'))
->to($user->getEmail())
->subject('Your password reset request')
->htmlTemplate('reset_password/email.html.twig')
->context([
'resetToken' => $resetToken,
'tokenLifetime' => $this->resetPasswordHelper->getTokenLifetime(),
]);
$mailer->send($email);
}
$this->addFlash(
'info',
'C’est dans la boite ! Vous avez reçu un email contenant un lien pour reinitialiser votre mot de passe. Ce lien expirera dans 2 heures.'
);
return $this->redirectToRoute('app_forgot_password_request');
}
}
from reset-password-bundle.
Your concept is not a bad idea, I'm a huge fan of reducing complexity. I have not attempted to run the code you suggest but just off the top of my head, here are a couple thoughts -
-
The code within the
if ($user) {
block adds an extra level of indentation within the if statement. While there is no hard fast rule on this, in-versingif ($user)
toif (!$user)
may be a better solution for readability. (Think exit/return early strategy) -
I'm not sure how I feel about the flash message for the "check your email" message. First thought that comes to mind is how would this affect caching as opposed to having a template. This may be an invalid point of my own.
-
If you use a flash message instead of the
check_email
route w/ template. In general, what happens when someone doesn't want to use flashes in their UI and the traditional templates. -
How does this affect the DX for translations. For a translation example - see the pending PR for the Symfony Demo app. e.g. symfony/demo#1100
There may be more that I am missing to this that would affect the UX (positively / negatively). Later tonight I'll spin up a demo of this and mess around with it.
None the less, if you were to submit these changes - you would have to do so in the Maker Bundle repository. @weaverryan Thoughts?
from reset-password-bundle.
thank you for your opinion. Yes, try the code. It works very well.
Question: I do not understand, why want to prohibit access to the view check_email? this is an unnecessary method. If a visitor wants to write, in his browser, the route to access check_email, he will see the message but it is not dangerous, it does not matter. The visitor has nothing else to do with his life. This condition is not necessary, I think. Sorry for my English, I use the translation to write, I'm sorry. I take note of your points, thank you.
from reset-password-bundle.
Hello!
I use the same function on Symfony ,but i have got a little issue:
When i submit the form it does everything by the way it must be , but i do not receive email.
Do you know where can be the problem?
Thank you!
from reset-password-bundle.
Hey @chaleto!
That could be a problem with the delivery of your email - like mailer config, or it's going to spam. A good way to see if Symfony actually "sent" the mail is to use the profiler. After completing the form, you can click the web debug toolbar to go into the profiler. You won't see it inside THIS profiler, because this is the profiler for the redirected request. But if you click the "Last 10" link and find the 2nd from the top - we should an example on this video https://symfonycasts.com/screencast/symfony-uploads/dropzone - it should be a POST request, then you can go into the Email section to see if the mail was delivered.
Cheers!
from reset-password-bundle.
Related Issues (20)
- Null Error during migration step HOT 3
- Some mandatory parameters are missing ("token") to generate a URL for route "app_reset_password". HOT 5
- Cannot find the entity manager for class "App\Entity\ResetPasswordRequest" HOT 2
- Token verification may fail for DateTime instances with milliseconds resolution
- Emails not send if use MailerInterface in private method proccessSendingResetEmail HOT 1
- Request: Allow to pass lifetime parameter in generateResetToken function on v1.14.1 version HOT 2
- Get not hashed token for functional testing HOT 2
- Errors after installation HOT 1
- Cannot find the entity manager for class "App\Entity\ResetPasswordRequest" HOT 6
- Error 500 when open url from Gmail or 365 web client HOT 3
- Support Symfony 7 HOT 3
- Flash message in request.html.twig HOT 2
- Hello! Tried to install the bundle on a fresh symfony 7 installation and it blocked the make:migration with an error: HOT 7
- Email not send . SendGrid , JWT Autentication, API Platfrom HOT 4
- ResetPasswordBundle v2.0
- ControllerTrait clear token HOT 2
- New password validaition constraints HOT 1
- [2.x] add test to ensure if lifetime is changed in userland - the new value is used in the helper
- [2.x] [tests] implement a solution to run `make:reset-password` command in tests
- Subject: How to Disable forgot-password Routes in ReDoc Documentation Only?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from reset-password-bundle.