commit21
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
|
||||
use Inertia\Testing\AssertableInertia as Assert;
|
||||
use PragmaRX\Google2FA\Google2FA;
|
||||
|
||||
require_once __DIR__.'/../../Support/FortifyMfa.php';
|
||||
|
||||
test('mfa management requires recent password confirmation without mutating enrollment on consultation', function () {
|
||||
foundationMfaRoutes();
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user)->get('/settings/security')->assertRedirect('/user/confirm-password');
|
||||
$this->postJson('/user/two-factor-authentication')->assertStatus(423);
|
||||
expect($user->fresh()->two_factor_secret)->toBeNull();
|
||||
$this->withSession(['auth.password_confirmed_at' => now()->timestamp])->get('/settings/security')->assertOk()
|
||||
->assertHeader('Cache-Control', 'max-age=0, no-store, private')->assertInertia(fn (Assert $p) => $p
|
||||
->where('canManageTwoFactor', true)->where('twoFactorEnabled', false)->where('twoFactorPending', false)->missing('secretKey')->missing('recoveryCodes'));
|
||||
expect($user->fresh()->two_factor_secret)->toBeNull();
|
||||
});
|
||||
|
||||
test('mfa management completes native enrollment renewal and disable only for the current account', function () {
|
||||
foundationMfaRoutes();
|
||||
$user = User::factory()->create();
|
||||
$other = User::factory()->create();
|
||||
$this->actingAs($user)->withSession(['auth.password_confirmed_at' => now()->timestamp]);
|
||||
$this->postJson('/user/two-factor-authentication', ['user_id' => $other->id])->assertSuccessful();
|
||||
$secret = $this->getJson('/user/two-factor-secret-key')->assertOk()->assertHeader('Cache-Control', 'max-age=0, no-store, private')->json('secretKey');
|
||||
expect($user->fresh()->hasEnabledTwoFactorAuthentication())->toBeFalse();
|
||||
$before = $user->fresh()->getAttributes();
|
||||
$this->get('/settings/security')->assertInertia(fn (Assert $p) => $p->where('twoFactorPending', true)->where('twoFactorEnabled', false)->missing('secretKey')->missing('recoveryCodes'));
|
||||
expect($user->fresh()->getAttributes())->toBe($before);
|
||||
$code = (new Google2FA)->getCurrentOtp($secret);
|
||||
$this->postJson('/user/confirmed-two-factor-authentication', ['code' => $code])->assertSuccessful();
|
||||
expect($user->fresh()->hasEnabledTwoFactorAuthentication())->toBeTrue();
|
||||
$oldCodes = $this->getJson('/user/two-factor-recovery-codes')->assertOk()->assertHeader('Cache-Control', 'max-age=0, no-store, private')->json();
|
||||
$this->postJson('/user/two-factor-recovery-codes')->assertSuccessful();
|
||||
$newCodes = $this->getJson('/user/two-factor-recovery-codes')->assertOk()->json();
|
||||
expect($oldCodes)->toHaveCount(8)->and($newCodes)->toHaveCount(8)->and(array_intersect($oldCodes, $newCodes))->toBe([]);
|
||||
$this->withSession(['auth.password_confirmed_at' => 0])->deleteJson('/user/two-factor-authentication')->assertStatus(423);
|
||||
expect($user->fresh()->hasEnabledTwoFactorAuthentication())->toBeTrue();
|
||||
$this->withSession(['auth.password_confirmed_at' => now()->timestamp])->deleteJson('/user/two-factor-authentication')->assertSuccessful();
|
||||
expect($user->fresh()->two_factor_secret)->toBeNull()->and($user->fresh()->two_factor_recovery_codes)->toBeNull()->and($user->fresh()->two_factor_confirmed_at)->toBeNull();
|
||||
expect($other->fresh()->two_factor_secret)->toBeNull();
|
||||
});
|
||||
|
||||
test('mfa management invalid confirmation does not flash authentication codes or activate the account', function () {
|
||||
foundationMfaRoutes();
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user)->withSession(['auth.password_confirmed_at' => now()->timestamp]);
|
||||
$this->postJson('/user/two-factor-authentication')->assertSuccessful();
|
||||
$this->from('/settings/security')->post('/user/confirmed-two-factor-authentication', ['code' => 'invalid'])->assertSessionHasErrorsIn('confirmTwoFactorAuthentication', ['code'])
|
||||
->assertSessionMissing('_old_input.code');
|
||||
expect($user->fresh()->hasEnabledTwoFactorAuthentication())->toBeFalse();
|
||||
});
|
||||
|
||||
test('mfa management rejects missing csrf and accepts the encrypted xsrf cookie header used by the interface', function () {
|
||||
foundationMfaRoutes();
|
||||
$this->instance(PreventRequestForgery::class,
|
||||
new class(app(), app('encrypter')) extends PreventRequestForgery
|
||||
{
|
||||
protected function runningUnitTests(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
$user = User::factory()->create();
|
||||
$response = $this->actingAs($user)->withSession(['auth.password_confirmed_at' => now()->timestamp])->get('/settings/security')->assertOk();
|
||||
$cookie = $response->getCookie('XSRF-TOKEN', false);
|
||||
expect($cookie)->not->toBeNull();
|
||||
$this->postJson('/user/two-factor-authentication')->assertStatus(419);
|
||||
expect($user->fresh()->two_factor_secret)->toBeNull();
|
||||
$this->withHeader('X-XSRF-TOKEN', $cookie->getValue())->postJson('/user/two-factor-authentication')->assertSuccessful();
|
||||
expect($user->fresh()->two_factor_secret)->not->toBeNull();
|
||||
});
|
||||
Reference in New Issue
Block a user