121 lines
3.5 KiB
PHP
121 lines
3.5 KiB
PHP
<?php
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Auth\Events\Verified;
|
|
use Illuminate\Auth\Notifications\VerifyEmail;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Facades\Event;
|
|
use Illuminate\Support\Facades\Notification;
|
|
use Illuminate\Support\Facades\URL;
|
|
use Tests\Feature\ApiTestCase;
|
|
|
|
beforeEach(function () {
|
|
$this->setSettings(['reg_enabled' => true]);
|
|
});
|
|
|
|
test('unauthenticated request cannot verify email', function () {
|
|
$this->postJson('api/email/verify')->assertStatus(401);
|
|
});
|
|
|
|
test('verify returns not found when email confirmation disabled', function () {
|
|
$this->setSettings(['reg_email_confirmation' => false]);
|
|
|
|
$user = $this->login();
|
|
|
|
$payload = validSignedPayload($user);
|
|
|
|
$this->postJson('api/email/verify', $payload)
|
|
->assertStatus(404);
|
|
});
|
|
|
|
test('verify succeeds for unverified user with valid signature', function () {
|
|
$this->setSettings(['reg_email_confirmation' => true]);
|
|
|
|
Event::fake([Verified::class]);
|
|
|
|
$user = User::factory()->create(['email_verified_at' => null]);
|
|
$this->be($user, ApiTestCase::API_GUARD);
|
|
|
|
$payload = validSignedPayload($user);
|
|
|
|
$this->postJson('api/email/verify', $payload)
|
|
->assertOk();
|
|
|
|
$this->assertNotNull($user->fresh()->email_verified_at);
|
|
Event::assertDispatched(Verified::class);
|
|
});
|
|
|
|
test('verify returns bad request when already verified', function () {
|
|
$this->setSettings(['reg_email_confirmation' => true]);
|
|
|
|
$user = User::factory()->create(['email_verified_at' => Carbon::now()]);
|
|
$this->be($user, ApiTestCase::API_GUARD);
|
|
|
|
$payload = validSignedPayload($user);
|
|
|
|
$this->postJson('api/email/verify', $payload)
|
|
->assertStatus(400);
|
|
});
|
|
|
|
test('verify fails with invalid signature', function () {
|
|
$this->setSettings(['reg_email_confirmation' => true]);
|
|
|
|
$user = User::factory()->create(['email_verified_at' => null]);
|
|
$this->be($user, ApiTestCase::API_GUARD);
|
|
|
|
$this->postJson('api/email/verify', [
|
|
'id' => $user->id,
|
|
'hash' => sha1($user->email),
|
|
'expires' => Carbon::now()->addMinutes(60)->timestamp,
|
|
'signature' => 'invalid-signature',
|
|
])->assertStatus(403);
|
|
|
|
$this->assertNull($user->fresh()->email_verified_at);
|
|
});
|
|
|
|
test('verify requires id hash expires signature', function () {
|
|
$this->login();
|
|
|
|
$this->postJson('api/email/verify', [])
|
|
->assertStatus(422)
|
|
->assertJsonValidationErrors(['id', 'hash', 'expires', 'signature']);
|
|
});
|
|
|
|
test('resend sends verification notification', function () {
|
|
Notification::fake();
|
|
|
|
$user = User::factory()->create(['email_verified_at' => null]);
|
|
$this->be($user, ApiTestCase::API_GUARD);
|
|
|
|
$this->postJson('api/email/resend')->assertStatus(202);
|
|
|
|
Notification::assertSentTo($user, VerifyEmail::class);
|
|
});
|
|
|
|
test('resend returns bad request for already verified user', function () {
|
|
$user = User::factory()->create(['email_verified_at' => Carbon::now()]);
|
|
$this->be($user, ApiTestCase::API_GUARD);
|
|
|
|
$this->postJson('api/email/resend')->assertStatus(400);
|
|
});
|
|
|
|
function validSignedPayload(User $user): array
|
|
{
|
|
$expires = Carbon::now()->addMinutes(60)->timestamp;
|
|
|
|
$signedUrl = URL::temporarySignedRoute(
|
|
'verification.verify',
|
|
Carbon::createFromTimestamp($expires),
|
|
['id' => $user->id, 'hash' => sha1($user->email)]
|
|
);
|
|
|
|
parse_str(parse_url($signedUrl, PHP_URL_QUERY), $query);
|
|
|
|
return [
|
|
'id' => $user->id,
|
|
'hash' => sha1($user->email),
|
|
'expires' => $query['expires'],
|
|
'signature' => $query['signature'],
|
|
];
|
|
}
|