Files
Investidor-V2/tests/Feature/PortalQaMfaTracePrivacyTest.php
T
nala 20971d523f
tests / ci (push) Canceled after 0s
oportunidades 6
2026-10-10 21:17:46 +02:00

54 lines
2.5 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'));
}
}