81 lines
2.9 KiB
PHP
81 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Livewire\Settings\Security;
|
|
use App\Livewire\Settings\WebauthnKeys;
|
|
use App\Models\User;
|
|
use App\Models\WebauthnCredential;
|
|
use App\Services\WebauthnService;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Livewire\Livewire;
|
|
use Mockery;
|
|
use Tests\TestCase;
|
|
|
|
class SettingsFactorManagementTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
Mockery::close();
|
|
parent::tearDown();
|
|
}
|
|
|
|
public function test_removing_totp_when_it_is_the_only_factor_clears_codes(): void
|
|
{
|
|
$user = User::factory()->create(['two_factor_secret' => 'S', 'two_factor_confirmed_at' => now()]);
|
|
$user->replaceRecoveryCodes();
|
|
|
|
Livewire::actingAs($user)->test(Security::class)->call('disableTwoFactor');
|
|
|
|
$fresh = $user->fresh();
|
|
$this->assertFalse($fresh->hasTotp());
|
|
$this->assertFalse($fresh->hasRecoveryCodes(), 'last factor removed → codes cleared');
|
|
}
|
|
|
|
public function test_removing_totp_keeps_codes_when_a_key_remains(): void
|
|
{
|
|
$user = User::factory()->create(['two_factor_secret' => 'S', 'two_factor_confirmed_at' => now()]);
|
|
WebauthnCredential::create(['user_id' => $user->id, 'name' => 'k', 'credential_id' => 'cid', 'public_key' => '{}', 'sign_count' => 0]);
|
|
$user->replaceRecoveryCodes();
|
|
|
|
Livewire::actingAs($user->fresh())->test(Security::class)->call('disableTwoFactor');
|
|
|
|
$fresh = $user->fresh();
|
|
$this->assertFalse($fresh->hasTotp());
|
|
$this->assertTrue($fresh->hasWebauthnCredentials());
|
|
$this->assertTrue($fresh->hasRecoveryCodes(), 'key remains → codes kept');
|
|
}
|
|
|
|
public function test_a_key_can_be_the_first_factor_without_existing_2fa(): void
|
|
{
|
|
$user = User::factory()->create();
|
|
|
|
$svc = Mockery::mock(WebauthnService::class);
|
|
$svc->shouldReceive('available')->andReturnTrue();
|
|
$svc->shouldReceive('registrationOptions')->andReturn(['ok' => true]);
|
|
app()->instance(WebauthnService::class, $svc);
|
|
|
|
Livewire::actingAs($user)->test(WebauthnKeys::class)
|
|
->set('newName', 'YubiKey')
|
|
->call('options', $svc)
|
|
->assertReturned(['ok' => true]);
|
|
}
|
|
|
|
public function test_removing_the_last_key_clears_codes(): void
|
|
{
|
|
$user = User::factory()->create();
|
|
$cred = WebauthnCredential::create(['user_id' => $user->id, 'name' => 'k', 'credential_id' => 'cid', 'public_key' => '{}', 'sign_count' => 0]);
|
|
$user->replaceRecoveryCodes();
|
|
|
|
$svc = Mockery::mock(WebauthnService::class);
|
|
$svc->shouldReceive('available')->andReturnTrue();
|
|
app()->instance(WebauthnService::class, $svc);
|
|
|
|
Livewire::actingAs($user->fresh())->test(WebauthnKeys::class)->call('remove', $cred->id, $svc);
|
|
|
|
$this->assertFalse($user->fresh()->hasRecoveryCodes());
|
|
}
|
|
}
|