fix: allow sending more invite in case of expirations (#745)

This commit is contained in:
JacquesDurand 2024-10-02 09:16:47 +02:00 committed by Hugo Nicolas
parent 06a76374bc
commit 030eb6c805
No known key found for this signature in database
GPG key ID: 09CB3D93EB8B0E61
7 changed files with 88 additions and 2 deletions

View file

@ -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
{

View file

@ -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.

View file

@ -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);

View file

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace App\Validator\Constraints\User;
use Symfony\Component\Validator\Constraint;
#[\Attribute(\Attribute::TARGET_CLASS)]
final class UniqueUser extends Constraint
{
public string $message = 'validator.user.unique.message';
public function getTargets(): string
{
return self::CLASS_CONSTRAINT;
}
}

View file

@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace App\Validator\Constraints\User;
use App\Entity\User;
use App\Repository\UserRepository;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Exception\UnexpectedValueException;
final class UniqueUserValidator extends ConstraintValidator
{
public function __construct(
private readonly UserRepository $userRepository,
) {
}
public function validate(mixed $value, Constraint $constraint): void
{
if (!$constraint instanceof UniqueUser) {
throw new UnexpectedTypeException($constraint, UniqueUser::class);
}
if (!$value instanceof User) {
throw new UnexpectedValueException($value, User::class);
}
$existingUser = $this->userRepository->findOneByEmail($value->getEmail());
if (null === $existingUser) {
return;
}
if (!$existingUser->isEmailConfirmed()) {
return;
}
$this->context->buildViolation($constraint->message)
->atPath('email')
->addViolation();
}
}

View file

@ -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';

View file

@ -11,6 +11,11 @@
<target>Veuillez remplir ce champ</target>
</trans-unit>
<trans-unit id="abcdef" resname="validator.user.unique.message">
<source>validator.user.unique.message</source>
<target>Cette valeur est déjà utilisée.</target>
</trans-unit>
</body>
</file>
</xliff>