Symfony 6 verify email only if logged in, but can't login if account not verified

147 Views Asked by At

I'm encountering an issue with the email verifier in my Symfony 6 project. I've integrated the EmailVerifier bundle for user registration, and I've also created a UserChecker to prevent login for users whose email addresses are not verified. However, I've run into a problem. There seems to be a catch-22 situation: you can't verify your email because the bundle requires you to be logged in to set 'isVerified' to 'true,' and at the same time, you can't log in because your account is not verified

UserCheck.php

<?php

namespace App\Security;

use App\Entity\User as AppUser;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAccountStatusException;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class UserChecker implements UserCheckerInterface
{

    public function checkPreAuth(UserInterface $user)
    {
        if (!$user instanceof AppUser) {
            return;
        }

        if(!$user->isVerified()) {
            throw new CustomUserMessageAccountStatusException('Votre compte n\'est pas encore vérifié. Veuillez cliquer sur le lien de vérification que vous avez reçu par e-mail.');
        }
    }

    public function checkPostAuth(UserInterface $user)
    {
        if (!$user instanceof AppUser) {
            return;
        }
    }
}

EmailVerifier.php

/**
     * @throws VerifyEmailExceptionInterface
     */
    public function handleEmailConfirmation(Request $request, UserInterface $user): void
    {
        $this->verifyEmailHelper->validateEmailConfirmation($request->getUri(), $user->getId(), $user->getEmail());

        $user->setIsVerified(true);

        $this->entityManager->persist($user);
        $this->entityManager->flush();
    }

RegistrationController.php

#[Route('/verify/email', name: 'app_verify_email')]
    public function verifyUserEmail(Request $request, TranslatorInterface $translator): Response
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');

        // validate email confirmation link, sets User::isVerified=true and persists
        try {
            $this->emailVerifier->handleEmailConfirmation($request, $this->getUser());
        } catch (VerifyEmailExceptionInterface $exception) {
            $this->addFlash('verify_email_error', $translator->trans($exception->getReason(), [], 'VerifyEmailBundle'));

            return $this->redirectToRoute('app_register');
        }

        // @TODO Change the redirect on success and handle or remove the flash message in your templates
        $this->addFlash('success', 'Votre adresse email a été vérifiée.');

        return $this->redirectToRoute('app_register');
    }

as you can see on the line : $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');, it requires to be authenticated

I attempted to edit these functions, but it appears that everything is tightly interwoven, and even a minor change in these functions provided by the Symfony bundle leads to a cascade of errors. Is there a more effective approach to achieve this? Thank you.

EDIT / Problem solved : When make registration form , it ask if you want add user id to verify email anonimously without login

0

There are 0 best solutions below