feat: use timestamp instead of bool on is_verified

This commit is contained in:
Maël Gangloff 2025-10-04 12:24:20 +02:00
parent b3d75228e9
commit 79589e63eb
No known key found for this signature in database
GPG Key ID: 11FDC81C24A7F629
6 changed files with 66 additions and 11 deletions

View File

@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20251004101245 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// 1. Ajouter les nouvelles colonnes sans contrainte NOT NULL
$this->addSql('ALTER TABLE "user" ADD created_at TIMESTAMP(0) WITHOUT TIME ZONE');
$this->addSql('ALTER TABLE "user" ADD verified_at TIMESTAMP(0) WITHOUT TIME ZONE');
$this->addSql('COMMENT ON COLUMN "user".created_at IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('COMMENT ON COLUMN "user".verified_at IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('UPDATE "user" SET created_at = TO_TIMESTAMP(0)');
$this->addSql('UPDATE "user" SET verified_at = TO_TIMESTAMP(0) WHERE is_verified = true');
$this->addSql('ALTER TABLE "user" ALTER COLUMN created_at SET NOT NULL');
$this->addSql('ALTER TABLE "user" DROP is_verified');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE "user" ADD is_verified BOOLEAN NOT NULL DEFAULT TRUE');
$this->addSql('ALTER TABLE "user" DROP created_at');
$this->addSql('ALTER TABLE "user" DROP verified_at');
}
}

View File

@ -73,10 +73,10 @@ class RegistrationController extends AbstractController
$user, $user,
$user->getPassword() $user->getPassword()
) )
); )->setCreatedAt(new \DateTimeImmutable());
if (false === (bool) $this->getParameter('registration_verify_email')) { if (false === (bool) $this->getParameter('registration_verify_email')) {
$user->setVerified(true); $user->setVerifiedAt($user->getCreatedAt());
} else { } else {
$email = $this->emailVerifier->sendEmailConfirmation('app_verify_email', $user, $email = $this->emailVerifier->sendEmailConfirmation('app_verify_email', $user,
(new TemplatedEmail()) (new TemplatedEmail())

View File

@ -75,7 +75,10 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
private Collection $connectors; private Collection $connectors;
#[ORM\Column] #[ORM\Column]
private bool $isVerified = false; private ?\DateTimeImmutable $createdAt = null;
#[ORM\Column(nullable: true)]
private ?\DateTimeImmutable $verifiedAt = null;
public function __construct() public function __construct()
{ {
@ -215,14 +218,26 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this; return $this;
} }
public function isVerified(): bool public function getCreatedAt(): ?\DateTimeImmutable
{ {
return $this->isVerified; return $this->createdAt;
} }
public function setVerified(bool $isVerified): static public function setCreatedAt(\DateTimeImmutable $createdAt): static
{ {
$this->isVerified = $isVerified; $this->createdAt = $createdAt;
return $this;
}
public function getVerifiedAt(): ?\DateTimeImmutable
{
return $this->verifiedAt;
}
public function setVerifiedAt(\DateTimeImmutable $verifiedAt): static
{
$this->verifiedAt = $verifiedAt;
return $this; return $this;
} }

View File

@ -47,7 +47,7 @@ readonly class EmailVerifier
{ {
$this->verifyEmailHelper->validateEmailConfirmationFromRequest($request, (string) $user->getId(), $user->getEmail()); $this->verifyEmailHelper->validateEmailConfirmationFromRequest($request, (string) $user->getId(), $user->getEmail());
$user->setVerified(true); $user->setVerifiedAt(new \DateTimeImmutable());
$this->entityManager->persist($user); $this->entityManager->persist($user);
$this->entityManager->flush(); $this->entityManager->flush();

View File

@ -33,7 +33,7 @@ class JWTAuthenticator implements AuthenticationSuccessHandlerInterface
public function handleAuthenticationSuccess(UserInterface $user, $jwt = null): Response public function handleAuthenticationSuccess(UserInterface $user, $jwt = null): Response
{ {
if (($user instanceof User) && !$user->isVerified()) { if (($user instanceof User) && null === $user->getVerifiedAt()) {
throw new AccessDeniedHttpException('You have not yet validated your email address.'); throw new AccessDeniedHttpException('You have not yet validated your email address.');
} }

View File

@ -57,8 +57,8 @@ class OAuthAuthenticator extends OAuth2Authenticator implements AuthenticationEn
return $existingUser; return $existingUser;
} }
$user = new User(); $user = (new User())->setCreatedAt(new \DateTimeImmutable());
$user->setEmail($userFromToken->getEmail())->setVerified(true); $user->setEmail($userFromToken->getEmail())->setVerifiedAt($user->getCreatedAt());
$this->em->persist($user); $this->em->persist($user);
$this->em->flush(); $this->em->flush();