Add email verification, organizer approval, and forgot password features
- Add isVerified, emailVerificationToken, emailVerifiedAt fields to User entity
- Send verification email on registration with token link
- Add /verification-email/{token} route to confirm email
- Send notification emails to organizer and staff on organizer email verification
- Add isApproved and offer fields to User entity for organizer approval workflow
- Auto-verify and auto-approve SSO Keycloak users with offer='custom'
- Add resetCode and resetCodeExpiresAt fields to User entity
- Create ForgotPasswordController with 2-step flow (email -> code + new password)
- Block forgot password for SSO users (no local password)
- Add "Mot de passe oublie" link on login page
- Create email templates: verification, reset_code, organizer_pending, organizer_request
- Add migrations for all new fields
- Add tests: ForgotPasswordControllerTest (9 tests), update RegistrationControllerTest,
update UserTest with verification, approval, offer, and reset code fields
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -88,6 +88,54 @@ class UserTest extends TestCase
|
||||
self::assertNull($user->getPhone());
|
||||
}
|
||||
|
||||
public function testResetCodeFields(): void
|
||||
{
|
||||
$user = new User();
|
||||
|
||||
self::assertNull($user->getResetCode());
|
||||
self::assertNull($user->getResetCodeExpiresAt());
|
||||
|
||||
$expiry = new \DateTimeImmutable('+15 minutes');
|
||||
$result = $user->setResetCode('123456')->setResetCodeExpiresAt($expiry);
|
||||
|
||||
self::assertSame($user, $result);
|
||||
self::assertSame('123456', $user->getResetCode());
|
||||
self::assertSame($expiry, $user->getResetCodeExpiresAt());
|
||||
}
|
||||
|
||||
public function testApprovalAndOfferFields(): void
|
||||
{
|
||||
$user = new User();
|
||||
|
||||
self::assertFalse($user->isApproved());
|
||||
self::assertNull($user->getOffer());
|
||||
|
||||
$result = $user->setIsApproved(true)->setOffer('custom');
|
||||
|
||||
self::assertSame($user, $result);
|
||||
self::assertTrue($user->isApproved());
|
||||
self::assertSame('custom', $user->getOffer());
|
||||
}
|
||||
|
||||
public function testEmailVerificationFields(): void
|
||||
{
|
||||
$user = new User();
|
||||
|
||||
self::assertFalse($user->isVerified());
|
||||
self::assertNull($user->getEmailVerificationToken());
|
||||
self::assertNull($user->getEmailVerifiedAt());
|
||||
|
||||
$now = new \DateTimeImmutable();
|
||||
$result = $user->setIsVerified(true)
|
||||
->setEmailVerificationToken('abc123')
|
||||
->setEmailVerifiedAt($now);
|
||||
|
||||
self::assertSame($user, $result);
|
||||
self::assertTrue($user->isVerified());
|
||||
self::assertSame('abc123', $user->getEmailVerificationToken());
|
||||
self::assertSame($now, $user->getEmailVerifiedAt());
|
||||
}
|
||||
|
||||
public function testEraseCredentialsDoesNotThrow(): void
|
||||
{
|
||||
$user = new User();
|
||||
|
||||
Reference in New Issue
Block a user