fix: allow sending more invite in case of expirations (#745)
This commit is contained in:
parent
06a76374bc
commit
030eb6c805
7 changed files with 88 additions and 2 deletions
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
18
src/Validator/Constraints/User/UniqueUser.php
Normal file
18
src/Validator/Constraints/User/UniqueUser.php
Normal 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;
|
||||
}
|
||||
}
|
||||
45
src/Validator/Constraints/User/UniqueUserValidator.php
Normal file
45
src/Validator/Constraints/User/UniqueUserValidator.php
Normal 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue