73 lines
3.5 KiB
PHP
73 lines
3.5 KiB
PHP
<?php
|
|
|
|
use App\Http\Middleware\EnterLocalEvaluation;
|
|
use App\Models\User;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Route;
|
|
use Inertia\Testing\AssertableInertia as Assert;
|
|
use Laravel\Fortify\Actions\EnableTwoFactorAuthentication;
|
|
use PragmaRX\Google2FA\Google2FA;
|
|
|
|
require_once __DIR__.'/../../Support/FortifyMfa.php';
|
|
|
|
beforeEach(function () {
|
|
foundationMfaRoutes();
|
|
app()->instance('env', 'payable-testing');
|
|
config(['public_navigation.enabled' => true]);
|
|
$this->withSession(['_token' => 'mfa-boundary-csrf']);
|
|
});
|
|
|
|
test('mfa evaluation boundary blocks password free entries before their handlers or data changes', function (string $method, string $path) {
|
|
$reached = false;
|
|
Route::middleware('web')->match([$method], $path, function () use (&$reached) {
|
|
$reached = true;
|
|
|
|
return response('unsafe demo handler');
|
|
});
|
|
$before = DB::table('users')->count();
|
|
$this->call($method, 'http://127.0.0.1:8005/'.$path, ['role' => 'admin', '_token' => 'mfa-boundary-csrf'])->assertRedirect('/login');
|
|
expect($reached)->toBeFalse()->and(DB::table('users')->count())->toBe($before)->and(DB::table('audit_logs')->count())->toBe(0);
|
|
$this->assertGuest();
|
|
})->with([
|
|
['GET', 'avaliar'], ['POST', 'avaliar/entrar'], ['GET', 'demo'], ['POST', 'demo/entrar'], ['POST', 'demo/sair'],
|
|
]);
|
|
|
|
test('mfa evaluation boundary requires normal credentials instead of automatic owner entry or public development navigation', function () {
|
|
$this->get('http://127.0.0.1:8005/dashboard')->assertRedirect('/login');
|
|
$this->assertGuest();
|
|
$this->get('http://127.0.0.1:8005/login')->assertOk()->assertInertia(fn (Assert $p) => $p->component('auth/login'));
|
|
expect(DB::table('users')->count())->toBe(0)->and(DB::table('audit_logs')->count())->toBe(0);
|
|
});
|
|
|
|
test('mfa evaluation boundary preserves the native password and authenticator challenge', function () {
|
|
$user = User::factory()->create();
|
|
app(EnableTwoFactorAuthentication::class)($user);
|
|
$user->forceFill(['two_factor_confirmed_at' => now()])->save();
|
|
$this->post('http://127.0.0.1:8005/login', ['email' => $user->email, 'password' => 'password', '_token' => 'mfa-boundary-csrf'])->assertRedirect('/two-factor-challenge');
|
|
$this->assertGuest();
|
|
$this->get('http://127.0.0.1:8005/dashboard')->assertRedirect('/login');
|
|
$this->assertGuest();
|
|
$code = (new Google2FA)->getCurrentOtp(decrypt($user->two_factor_secret));
|
|
$this->post('http://127.0.0.1:8005/two-factor-challenge', ['code' => $code, '_token' => session()->token()])->assertRedirect();
|
|
$this->assertAuthenticatedAs($user);
|
|
});
|
|
|
|
test('mfa evaluation boundary never switches an authenticated account through a demo shortcut', function () {
|
|
$user = User::factory()->create();
|
|
$this->actingAs($user);
|
|
$reached = false;
|
|
$next = function () use (&$reached) {
|
|
$reached = true;
|
|
|
|
return response('unsafe demo handler');
|
|
};
|
|
$before = $user->fresh()->getAttributes();
|
|
$request = Request::create('http://127.0.0.1:8005/demo/entrar', 'POST', ['role' => 'validacao']);
|
|
$request->setUserResolver(fn () => $user);
|
|
$response = app(EnterLocalEvaluation::class)->handle($request, $next);
|
|
expect($response->getStatusCode())->toBe(302)->and($response->headers->get('Location'))->toBe(url('/login'));
|
|
$this->assertAuthenticatedAs($user);
|
|
expect($reached)->toBeFalse()->and($user->fresh()->getAttributes())->toBe($before)->and(DB::table('users')->count())->toBe(1);
|
|
});
|