Open bastien70 opened 3 years ago
Related to #35
Howdy @bastien70 - adding the ability to generate a new verification link is something that is currently planned.. I believe the functionality will be added to the templates in MakerBundle
but I'm not 100% positive on that yet. Stay tuned for more information on this...
HI do you have information for this new feature ? Date or delay because on my application i want them
yo can add a route to request new link :
/**
* requestVerifyUserEmail
*/
#[Route('/request-verify-email', name: 'app_request_verify_email')]
public function requestVerifyUserEmail(
Request $request,
UserRepository $userRepository
): Response {
if ($this->getUser()) {
return $this->redirectToRoute('app_home');
}
$form = $this->createForm(RequestVerifyUserEmailFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// generate a signed url and email it to the user
$user = $userRepository->findOneByEmail($form->get('email')->getData());
if ($user) {
$this->emailVerifier->sendEmailConfirmation(
'app_verify_email',
$user,
(new TemplatedEmail())
->from(new Address('email@example.com', 'Sender'))
->to($user->getEmail())
->subject('Validation Link')
->htmlTemplate('security/registration/confirmation_email.html.twig')
);
// do anything else you need here, like flash message
$this->addFlash('success', 'blabla.');
return $this->redirectToRoute('app_home');
} else {
$this->addFlash('error', 'Email inconnu.');
}
}
return $this->render('security/registration/request.html.twig', [
'requestForm' => $form->createView(),
]);
}
and a form RequestVerifyUserEmailFormType
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class RequestVerifyUserEmailFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('email', EmailType::class, [
'attr' => ['autocomplete' => 'email'],
'constraints' => [
new NotBlank([
'message' => 'Merci de saisir votre email',
]),
],
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([]);
}
}
@latrach thanks for sharing this solution
Idea:
Currently, in the verifyUserEmail()
method of the RegistrationController
class, we handle exceptions using VerifyEmailExceptionInterface
after attempting to verify the user's email. The proposal is to handle the more specific exception, ExpiredSignatureException
, before the more general exception, VerifyEmailExceptionInterface
.
Details:
Currently, we have the following code:
try {
$this->emailVerifier->handleEmailConfirmation($request, $this->getUser());
} catch (VerifyEmailExceptionInterface $exception) {
$this->addFlash('verify_email_error', $exception->getReason());
return $this->redirectToRoute('app_register');
}
Suggestion:
My suggestion is to adjust the structure of the try
and catch
block as follows:
try {
$this->emailVerifier->handleEmailConfirmation($request, $this->getUser());
} catch (ExpiredSignatureException $expiredException) {
// Remove the user from the database, as the token has expired
// This allows the user to re-register
// and subsequently resend the email with the confirmation link
// Additionally, redirect the user to the registration process again
// The absence of the user in the database means the user can redo their registration
return $this->redirectToRoute('app_register');
} catch (VerifyEmailExceptionInterface $genericException) {
$this->addFlash('verify_email_error', $genericException->getReason());
return $this->redirectToRoute('app_register');
}
Benefits:
This approach not only enhances how we deal with expired verification tokens but also contributes to a cleaner and clearer registration flow for users.
@latrach thank you! I think this solution should be integrated by default to the bundle
Hey! When my user tries to log in when he is not activated, I display a notification telling him to activate his account, and I add a "Resend activation email" link.
If I want to be able to manage this, I will be forced, each time a user tries to connect, to generate a new unique link allowing them to access a route that will use the bundle to send a confirmation email.
In my UserChecker.php class :
The bundle should really be able to integrate this functionality directly.
To counter this, I thought about using another of your bundles. The symfonycasts/reset-password-bundle
By creating a "ResendConfirmationEmailRequest" entity which is a full clone of the "ResetPasswordRequest" entity from your other bundle. And use the same methods to generate a unique signature to allow a user to receive a confirmation email again.
What do you think ?