diff --git a/src/Tech/Controller/ActivationController.php b/src/Tech/Controller/ActivationController.php
index f467829..c2dcc3b 100644
--- a/src/Tech/Controller/ActivationController.php
+++ b/src/Tech/Controller/ActivationController.php
@@ -31,7 +31,7 @@ class ActivationController extends AbstractController
try {
$emailVerifier->handleEmailConfirmation($request, $user);
} catch (VerifyEmailExceptionInterface $exception) {
- $this->addFlash('error', $exception->getReason());
+ $this->addFlash('error', $exception->getReason() . ' If the link has expired, you can request a new one here.');
return $this->redirectToRoute('app_register');
}
diff --git a/src/Tech/Controller/RegistrationController.php b/src/Tech/Controller/RegistrationController.php
index 7cb2d20..55d29f6 100644
--- a/src/Tech/Controller/RegistrationController.php
+++ b/src/Tech/Controller/RegistrationController.php
@@ -4,6 +4,8 @@ namespace App\Tech\Controller;
use App\Tech\Entity\User;
use App\Tech\Form\RegistrationFormType;
+use App\Tech\Form\ResendVerificationEmailFormType;
+use App\Tech\Repository\UserRepository;
use App\Tech\Service\EmailVerifier;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
@@ -54,4 +56,41 @@ class RegistrationController extends AbstractController
'registrationForm' => $form->createView(),
]);
}
+
+ #[Route('/verify/resend', name: 'app_verify_resend_email')]
+ public function resendVerificationEmail(Request $request, UserRepository $userRepository, EmailVerifier $emailVerifier): Response
+ {
+ $form = $this->createForm(ResendVerificationEmailFormType::class);
+ $form->handleRequest($request);
+
+ if ($form->isSubmitted() && $form->isValid()) {
+ $email = $form->get('email')->getData();
+ $user = $userRepository->findOneBy(['email' => $email]);
+
+ if ($user) {
+ if (!$user->isVerified()) {
+ $emailVerifier->sendEmailConfirmation('app_verify_email', $user,
+ (new TemplatedEmail())
+ ->from($this->getParameter('mailer_from'))
+ ->to($user->getEmail())
+ ->subject('Please Confirm your Email')
+ ->htmlTemplate('tech/registration/confirmation_email.html.twig')
+ );
+ } else {
+ $this->addFlash('info', 'This email address is already verified.');
+ return $this->redirectToRoute('app_login');
+ }
+ }
+
+ // We show the same success message regardless of whether the user exists or not,
+ // to avoid revealing whether an email is registered.
+ $this->addFlash('success', 'If an account exists with this email, a new confirmation link has been sent.');
+
+ return $this->redirectToRoute('website_home');
+ }
+
+ return $this->render('tech/registration/resend_verification_email.html.twig', [
+ 'resendForm' => $form->createView(),
+ ]);
+ }
}
diff --git a/src/Tech/Form/ResendVerificationEmailFormType.php b/src/Tech/Form/ResendVerificationEmailFormType.php
new file mode 100644
index 0000000..e1d5d17
--- /dev/null
+++ b/src/Tech/Form/ResendVerificationEmailFormType.php
@@ -0,0 +1,34 @@
+add('email', EmailType::class, [
+ 'constraints' => [
+ new NotBlank([
+ 'message' => 'Please enter your email',
+ ]),
+ new Email([
+ 'message' => 'Please enter a valid email address',
+ ]),
+ ],
+ ])
+ ;
+ }
+
+ public function configureOptions(OptionsResolver $resolver): void
+ {
+ $resolver->setDefaults([]);
+ }
+}
diff --git a/src/Tech/Service/UserChecker.php b/src/Tech/Service/UserChecker.php
index 11a621e..66d6558 100644
--- a/src/Tech/Service/UserChecker.php
+++ b/src/Tech/Service/UserChecker.php
@@ -3,6 +3,7 @@
namespace App\Tech\Service;
use App\Tech\Entity\User;
+use Symfony\Component\Security\Core\Exception\AccountStatusException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;
@@ -16,7 +17,7 @@ class UserChecker implements UserCheckerInterface
}
if (!$user->isVerified()) {
- throw new CustomUserMessageAuthenticationException('Your email address is not verified.');
+ throw new CustomUserMessageAuthenticationException('Your email address is not verified.', ['%resend_link%' => '/verify/resend']);
}
}
diff --git a/templates/tech/registration/confirmation_email.html.twig b/templates/tech/registration/confirmation_email.html.twig
index bc307f2..b256fa1 100644
--- a/templates/tech/registration/confirmation_email.html.twig
+++ b/templates/tech/registration/confirmation_email.html.twig
@@ -4,6 +4,7 @@
Please confirm your email address by clicking the following link:
Confirm my Email.
This link will expire in {{ expiresAtMessageKey|trans(expiresAtMessageData, 'VerifyEmailBundle') }}.
+ If the link has expired or doesn't work, you can request a new one.
diff --git a/templates/tech/registration/resend_verification_email.html.twig b/templates/tech/registration/resend_verification_email.html.twig new file mode 100644 index 0000000..556e1f2 --- /dev/null +++ b/templates/tech/registration/resend_verification_email.html.twig @@ -0,0 +1,17 @@ +{% extends 'base.html.twig' %} + +{% block title %}Resend verification email{% endblock %} + +{% block body %} +
Enter your email address and we will send you a new link to verify your account.
+ + {{ form_errors(resendForm) }} + + {{ form_start(resendForm) }} + {{ form_row(resendForm.email) }} + + + {{ form_end(resendForm) }} +{% endblock %} diff --git a/templates/tech/security/login.html.twig b/templates/tech/security/login.html.twig index 8d4fb16..2e0b1a6 100644 --- a/templates/tech/security/login.html.twig +++ b/templates/tech/security/login.html.twig @@ -5,7 +5,12 @@ {% block body %} {% endblock %}