feat: fix verify email
Laravel CI-CD / Tests Unitaires (push) Successful in 22s Details
Laravel CI-CD / Deploy with Kamal (push) Successful in 1m46s Details

This commit is contained in:
Leon Morival 2026-05-20 23:17:25 +02:00
parent 789eadb544
commit ec912bf4fe
3 changed files with 37 additions and 3 deletions

View File

@ -42,6 +42,20 @@ class AppServiceProvider extends ServiceProvider
Notification::extend('expo', fn ($app) => $app->make(ExpoPushChannel::class));
VerifyEmail::createUrlUsing(function (User $notifiable): string {
$relativeUrl = URL::temporarySignedRoute(
'verification.verify',
now()->addMinutes((int) config('auth.verification.expire', 60)),
[
'id' => $notifiable->getKey(),
'hash' => sha1($notifiable->getEmailForVerification()),
],
absolute: false,
);
return url($relativeUrl);
});
VerifyEmail::toMailUsing(
fn (User $notifiable, string $verificationUrl): VerifyAccount => (new VerifyAccount($notifiable, $verificationUrl))
->to($notifiable->getEmailForVerification())

View File

@ -14,7 +14,7 @@ Route::prefix('auth')->group(function (): void {
Route::post('register', [AuthController::class, 'register']);
Route::post('login', [AuthController::class, 'login']);
Route::get('email/verify/{id}/{hash}', [AuthController::class, 'verifyEmail'])
->middleware(['signed', 'throttle:6,1'])
->middleware(['signed:relative', 'throttle:6,1'])
->name('verification.verify');
Route::post('email/verification-notification', [AuthController::class, 'sendVerificationEmail'])
->middleware('throttle:6,1')

View File

@ -41,12 +41,32 @@ it('uses the custom account verification mailable', function () {
->assertSeeInHtml($user->name);
});
it('generates verification links with a relative signature', function () {
$user = User::factory()->unverified()->create();
$verificationUrl = (new VerifyEmail)->toMail($user)->verificationUrl;
expect($verificationUrl)->toContain('/api/auth/email/verify/')
->and($verificationUrl)->toContain('signature=');
$urlParts = parse_url($verificationUrl);
$requestUrl = ($urlParts['path'] ?? '').'?'.($urlParts['query'] ?? '');
$this
->withServerVariables(['HTTP_HOST' => 'different-host.test'])
->getJson($requestUrl)
->assertOk()
->assertJsonPath('message', __('api.auth.verified'));
expect($user->fresh()->hasVerifiedEmail())->toBeTrue();
});
it('verifies a user from a signed email link', function () {
$user = User::factory()->unverified()->create();
$url = URL::temporarySignedRoute('verification.verify', now()->addMinutes(60), [
'id' => $user->getKey(),
'hash' => sha1($user->email),
]);
], absolute: false);
$this->getJson($url)
->assertOk()
@ -61,7 +81,7 @@ it('rejects signed verification links with an invalid hash', function () {
$url = URL::temporarySignedRoute('verification.verify', now()->addMinutes(60), [
'id' => $user->getKey(),
'hash' => sha1('wrong-address@example.com'),
]);
], absolute: false);
$this->getJson($url)->assertForbidden();