Files
Investidor-V2/tests/Feature/PortalQaMfaTracePrivacyTest.php
T
nala 287e991486
tests / ci (push) Waiting to run
oportunidades 7
2026-10-13 11:40:29 +02:00

56 lines
2.6 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Request;
use Illuminate\Session\ArraySessionHandler;
use Illuminate\Session\Store;
use Laravel\Fortify\Contracts\TwoFactorAuthenticationProvider;
use PragmaRX\Google2FA\Google2FA;
use Symfony\Component\HttpFoundation\Response;
use Tests\TestCase;
class PortalQaMfaTracePrivacyTest extends TestCase
{
use RefreshDatabase;
public function test_diagnostic_distinguishes_replay_without_consuming_code_or_authenticating(): void
{
require_once base_path('tools/portal-qa-auth-trace.php');
config(['cache.default' => 'array']);
$engine = new Google2FA;
$secret = $engine->generateSecretKey();
User::factory()->create(['id' => 18, 'email' => 'investor-mfa-qa@example.invalid', 'two_factor_secret' => encrypt($secret), 'two_factor_confirmed_at' => now()]);
$code = $engine->getCurrentOtp($secret);
$request = Request::create('/two-factor-challenge', 'POST', ['code' => $code]);
$session = new Store('qa_trace_unit', new ArraySessionHandler(120));
$session->start();
$session->put('login.id', 18);
$request->setLaravelSession($session);
$request->attributes->set('qa_auth_trace', 'unit');
$trace = new \PortalQaSessionTrace;
$trace->handle($request, fn () => new Response('controlled'));
$first = $request->attributes->get('qa_mfa_input_check');
$this->assertTrue($first['secret_decrypts']);
$this->assertTrue($first['matches_configured_time_window']);
$this->assertFalse($first['previously_used_in_cache']);
$this->assertTrue($first['accepted_by_replay_check']);
$this->assertFalse(auth()->check());
// Fortify must still accept the unused code: the diagnostic cannot consume it.
$this->assertTrue(app(TwoFactorAuthenticationProvider::class)->verify($secret, $code));
$trace->handle($request, fn () => new Response('controlled'));
$second = $request->attributes->get('qa_mfa_input_check');
$this->assertTrue($second['matches_configured_time_window']);
$this->assertTrue($second['previously_used_in_cache']);
$this->assertFalse($second['accepted_by_replay_check']);
$this->assertFalse(auth()->check());
$encoded = json_encode($second, JSON_THROW_ON_ERROR);
foreach ([$secret, $code, md5($code)] as $value) {
$this->assertStringNotContainsString($value, $encoded);
}
$this->assertSame(18, $session->get('login.id'));
}
}