diff --git a/src/Entity/User.php b/src/Entity/User.php index 88c2500..687abf7 100755 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -18,6 +18,7 @@ use App\Form\Type\User\ChangePasswordFormType; use App\Form\Type\User\EditProfileFormType; use App\Repository\UserRepository; use App\Validator\Constraints\User\MembershipPaid; +use App\Validator\Constraints\User\UniqueUser; use Carbon\Carbon; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -44,7 +45,8 @@ use function Symfony\Component\String\u; #[ORM\Index(columns: ['lost_password_token'])] #[ORM\Table(name: '`user`')] // we also need escaping here #[ORM\EntityListeners([UserListener::class])] -#[UniqueEntity('email', groups: [AccountCreateStep1FormType::class, ChangeLoginFormType::class, 'Default'])] +#[UniqueUser(groups: [AccountCreateStep1FormType::class, ChangeLoginFormType::class])] +#[UniqueEntity('email', groups: ['Default'])] #[MembershipPaid] class User implements UserInterface, PasswordAuthenticatedUserInterface, ImageInterface, EquatableInterface { diff --git a/src/MessageHandler/Command/Product/CreateGroupInvitationMessageHandler.php b/src/MessageHandler/Command/Product/CreateGroupInvitationMessageHandler.php index da39fd9..68c3290 100644 --- a/src/MessageHandler/Command/Product/CreateGroupInvitationMessageHandler.php +++ b/src/MessageHandler/Command/Product/CreateGroupInvitationMessageHandler.php @@ -58,6 +58,9 @@ final class CreateGroupInvitationMessageHandler $user = $this->userManager->getStep1User($message->email); $this->userManager->save($user, true); $isNewUser = true; + } elseif (!$user->isEmailConfirmed()) { + $this->userManager->refreshConfirmationToken($user); + $isNewUser = true; } // now create the invitation to the group. diff --git a/src/MessageHandler/Command/Security/AccountCreateStep1CommandHandler.php b/src/MessageHandler/Command/Security/AccountCreateStep1CommandHandler.php index 6a91d81..ecbbdbc 100644 --- a/src/MessageHandler/Command/Security/AccountCreateStep1CommandHandler.php +++ b/src/MessageHandler/Command/Security/AccountCreateStep1CommandHandler.php @@ -9,6 +9,7 @@ use App\Entity\User; use App\Mailer\AppMailer; use App\Mailer\Email\Security\CreateAccountStep1Email; use App\Message\Command\Security\AccountCreateStep1Command; +use App\Repository\UserRepository; use Symfony\Component\Messenger\Attribute\AsMessageHandler; #[AsMessageHandler] @@ -20,6 +21,7 @@ final class AccountCreateStep1CommandHandler public function __construct( private readonly UserManager $userManager, private readonly AppMailer $appMailer, + private readonly UserRepository $userRepository, ) { } @@ -31,6 +33,17 @@ final class AccountCreateStep1CommandHandler */ public function __invoke(AccountCreateStep1Command $message): void { + $existingUser = $this->userRepository->findOneByEmail($message->email); + if ($existingUser instanceof User) { + if (!$existingUser->isEmailConfirmed()) { + $this->userManager->refreshConfirmationToken($existingUser); + $this->userManager->save($existingUser, true); + $this->appMailer->send(CreateAccountStep1Email::class, ['user' => $existingUser]); + + return; + } + } + $user = new User(); $user->setEmail($message->email); $this->userManager->refreshConfirmationToken($user); diff --git a/src/Validator/Constraints/User/UniqueUser.php b/src/Validator/Constraints/User/UniqueUser.php new file mode 100644 index 0000000..c3f7159 --- /dev/null +++ b/src/Validator/Constraints/User/UniqueUser.php @@ -0,0 +1,18 @@ +userRepository->findOneByEmail($value->getEmail()); + + if (null === $existingUser) { + return; + } + + if (!$existingUser->isEmailConfirmed()) { + return; + } + + $this->context->buildViolation($constraint->message) + ->atPath('email') + ->addViolation(); + } +} diff --git a/tests/TestReference.php b/tests/TestReference.php index f0f249a..ed3efda 100644 --- a/tests/TestReference.php +++ b/tests/TestReference.php @@ -9,7 +9,7 @@ final class TestReference // common public const UUID_404 = '1ed7a2a8-0a77-6dbc-a404-040404040404'; // valid UUID for 404 pages public const VALIDATION_ERROR_BLANK = 'This value should not be blank'; - public const VALIDATION_ERROR_ALREADY_USED = 'This value is already used'; + public const VALIDATION_ERROR_ALREADY_USED = 'validator.user.unique.message'; // EasyAdmin public const ADMIN_URL = '/admin?crudAction=%s&crudControllerFqcn=%s'; diff --git a/translations/user/validators.fr.xlf b/translations/user/validators.fr.xlf index 232d9a5..cc175b2 100644 --- a/translations/user/validators.fr.xlf +++ b/translations/user/validators.fr.xlf @@ -11,6 +11,11 @@ Veuillez remplir ce champ + + validator.user.unique.message + Cette valeur est déjà utilisée. + +