2022-03-31 08:38:35 +02:00
|
|
|
<?php
|
|
|
|
|
2022-03-31 12:09:25 +02:00
|
|
|
namespace Tests\Feature\Http\Auth;
|
2022-03-31 08:38:35 +02:00
|
|
|
|
|
|
|
use App\Models\User;
|
|
|
|
use Illuminate\Support\Facades\Notification;
|
2022-11-22 15:15:52 +01:00
|
|
|
use Tests\FeatureTestCase;
|
2022-12-09 10:52:17 +01:00
|
|
|
use App\Notifications\WebauthnRecoveryNotification;
|
|
|
|
use Illuminate\Support\Facades\Lang;
|
2022-03-31 08:38:35 +02:00
|
|
|
|
2022-12-09 10:52:17 +01:00
|
|
|
/**
|
|
|
|
* @covers \App\Http\Controllers\Auth\WebAuthnDeviceLostController
|
|
|
|
* @covers \App\Notifications\WebauthnRecoveryNotification
|
|
|
|
* @covers \App\Extensions\WebauthnCredentialBroker
|
|
|
|
* @covers \App\Http\Requests\WebauthnDeviceLostRequest
|
|
|
|
* @covers \App\Providers\AuthServiceProvider
|
|
|
|
*/
|
2022-03-31 08:38:35 +02:00
|
|
|
class WebAuthnDeviceLostControllerTest extends FeatureTestCase
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var \App\Models\User
|
2022-11-22 15:15:52 +01:00
|
|
|
*/
|
2022-03-31 08:38:35 +02:00
|
|
|
protected $user;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @test
|
|
|
|
*/
|
2022-12-09 10:52:17 +01:00
|
|
|
public function setUp(): void
|
2022-03-31 08:38:35 +02:00
|
|
|
{
|
|
|
|
parent::setUp();
|
|
|
|
|
|
|
|
$this->user = User::factory()->create();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @test
|
2022-12-09 10:52:17 +01:00
|
|
|
* @covers \App\Models\Traits\WebAuthnManageCredentials
|
2022-03-31 08:38:35 +02:00
|
|
|
*/
|
|
|
|
public function test_sendRecoveryEmail_sends_notification_on_success()
|
|
|
|
{
|
|
|
|
Notification::fake();
|
|
|
|
|
|
|
|
$response = $this->json('POST', '/webauthn/lost', [
|
|
|
|
'email' => $this->user->email,
|
|
|
|
]);
|
|
|
|
|
2022-12-09 10:52:17 +01:00
|
|
|
Notification::assertSentTo($this->user, WebauthnRecoveryNotification::class);
|
2022-03-31 08:38:35 +02:00
|
|
|
|
|
|
|
$response->assertStatus(200)
|
2022-12-09 10:52:17 +01:00
|
|
|
->assertJsonStructure([
|
|
|
|
'message',
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->assertDatabaseHas('webauthn_recoveries', [
|
|
|
|
'email' => $this->user->email
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @test
|
|
|
|
*/
|
|
|
|
public function test_WebauthnRecoveryNotification_renders_to_email()
|
|
|
|
{
|
|
|
|
$mail = (new WebauthnRecoveryNotification('test_token'))->toMail($this->user)->render();
|
|
|
|
|
|
|
|
$this->assertStringContainsString(
|
|
|
|
'http://localhost/webauthn/recover?token=test_token&email=' . urlencode($this->user->email),
|
|
|
|
$mail
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertStringContainsString(
|
|
|
|
Lang::get('Recover Account'),
|
|
|
|
$mail
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertStringContainsString(
|
|
|
|
Lang::get(
|
|
|
|
'You are receiving this email because we received an account recovery request for your account.'
|
|
|
|
),
|
|
|
|
$mail
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertStringContainsString(
|
|
|
|
Lang::get(
|
|
|
|
'This recovery link will expire in :count minutes.',
|
|
|
|
['count' => config('auth.passwords.webauthn.expire')]
|
|
|
|
),
|
|
|
|
$mail
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->assertStringContainsString(
|
|
|
|
Lang::get('If you did not request an account recovery, no further action is required.'),
|
|
|
|
$mail
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @test
|
|
|
|
*/
|
|
|
|
public function test_sendRecoveryEmail_does_not_send_anything_to_unknown_email()
|
|
|
|
{
|
|
|
|
Notification::fake();
|
|
|
|
|
|
|
|
$response = $this->json('POST', '/webauthn/lost', [
|
|
|
|
'email' => 'bad@email.com',
|
|
|
|
]);
|
|
|
|
|
|
|
|
Notification::assertNothingSent();
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
->assertJsonValidationErrors([
|
|
|
|
'email',
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->assertDatabaseMissing('webauthn_recoveries', [
|
|
|
|
'email' => 'bad@email.com'
|
2022-03-31 08:38:35 +02:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @test
|
|
|
|
*/
|
2022-12-09 10:52:17 +01:00
|
|
|
public function test_sendRecoveryEmail_does_not_send_anything_to_invalid_email()
|
2022-03-31 08:38:35 +02:00
|
|
|
{
|
|
|
|
Notification::fake();
|
|
|
|
|
|
|
|
$response = $this->json('POST', '/webauthn/lost', [
|
|
|
|
'email' => 'bad@email.com',
|
|
|
|
]);
|
|
|
|
|
|
|
|
Notification::assertNothingSent();
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
2022-12-09 10:52:17 +01:00
|
|
|
->assertJsonValidationErrors([
|
|
|
|
'email',
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->assertDatabaseMissing('webauthn_recoveries', [
|
|
|
|
'email' => 'bad@email.com'
|
2022-03-31 08:38:35 +02:00
|
|
|
]);
|
|
|
|
}
|
2022-12-09 10:52:17 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @test
|
|
|
|
*/
|
|
|
|
public function test_sendRecoveryEmail_does_not_send_anything_to_not_WebAuthnAuthenticatable()
|
|
|
|
{
|
|
|
|
$mock = $this->mock(\App\Extensions\WebauthnCredentialBroker::class)->makePartial();
|
|
|
|
$mock->shouldReceive('getUser')
|
|
|
|
->andReturn(new \Illuminate\Foundation\Auth\User());
|
|
|
|
|
|
|
|
Notification::fake();
|
|
|
|
|
|
|
|
$response = $this->json('POST', '/webauthn/lost', [
|
|
|
|
'email' => $this->user->email,
|
|
|
|
]);
|
|
|
|
|
|
|
|
Notification::assertNothingSent();
|
|
|
|
|
|
|
|
$response->assertStatus(422)
|
|
|
|
->assertJsonValidationErrors([
|
|
|
|
'email',
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @test
|
|
|
|
*/
|
|
|
|
public function test_sendRecoveryEmail_is_throttled()
|
|
|
|
{
|
|
|
|
Notification::fake();
|
|
|
|
|
|
|
|
$response = $this->json('POST', '/webauthn/lost', [
|
|
|
|
'email' => $this->user->email,
|
|
|
|
]);
|
|
|
|
|
|
|
|
Notification::assertSentTo($this->user, WebauthnRecoveryNotification::class);
|
|
|
|
|
|
|
|
$response->assertStatus(200)
|
|
|
|
->assertJsonStructure([
|
|
|
|
'message',
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->assertDatabaseHas('webauthn_recoveries', [
|
|
|
|
'email' => $this->user->email
|
|
|
|
]);
|
|
|
|
|
|
|
|
$this->json('POST', '/webauthn/lost', [
|
|
|
|
'email' => $this->user->email,
|
|
|
|
])
|
|
|
|
->assertStatus(422)
|
|
|
|
->assertJsonValidationErrorfor('email')
|
|
|
|
->assertJsonFragment([
|
|
|
|
'message' => __('passwords.throttled')
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @test
|
|
|
|
*/
|
|
|
|
public function test_error_if_no_broker_is_set()
|
|
|
|
{
|
|
|
|
$this->app['config']->set('auth.passwords.webauthn', null);
|
|
|
|
|
|
|
|
$this->json('POST', '/webauthn/lost', [
|
|
|
|
'email' => $this->user->email
|
|
|
|
])
|
|
|
|
->assertStatus(500);
|
|
|
|
}
|
2022-11-22 15:15:52 +01:00
|
|
|
}
|