fix: prevent duplicate 2FA challenge submissions causing HTTP 419
This commit is contained in:
parent
0764ec425d
commit
953726f847
2 changed files with 51 additions and 2 deletions
|
|
@ -2,8 +2,18 @@
|
|||
<x-auth.shell title="Coolify" description="Verify your identity to finish signing in.">
|
||||
<div class="flex flex-col gap-4" x-data="{
|
||||
showRecovery: false,
|
||||
submitting: false,
|
||||
digits: ['', '', '', '', '', ''],
|
||||
code: '',
|
||||
handleSubmit(event) {
|
||||
if (this.submitting) {
|
||||
event.preventDefault();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.submitting = true;
|
||||
},
|
||||
focusNext(event) {
|
||||
const nextInput = event.target.nextElementSibling;
|
||||
if (nextInput?.tagName === 'INPUT') nextInput.focus();
|
||||
|
|
@ -52,7 +62,8 @@
|
|||
<p x-show="showRecovery" x-cloak>Enter one of the recovery codes you saved when setting up two-factor authentication.</p>
|
||||
</div>
|
||||
|
||||
<form x-ref="challengeForm" action="/two-factor-challenge" method="POST" class="flex flex-col gap-4">
|
||||
<form x-ref="challengeForm" action="/two-factor-challenge" method="POST" class="flex flex-col gap-4"
|
||||
@submit="handleSubmit($event)">
|
||||
@csrf
|
||||
|
||||
<div x-show="!showRecovery" class="flex flex-col gap-3">
|
||||
|
|
@ -82,7 +93,7 @@ class="h-12 w-11 rounded-md border border-neutral-300 bg-white text-center text-
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<x-forms.button class="w-full justify-center" type="submit" isHighlighted>
|
||||
<x-forms.button class="w-full justify-center" type="submit" x-bind:disabled="submitting" isHighlighted>
|
||||
Verify and continue
|
||||
</x-forms.button>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Laravel\Fortify\Fortify;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
|
|
@ -69,6 +70,43 @@
|
|||
->screenshot(filename: 'login-invalid-credentials');
|
||||
});
|
||||
|
||||
it('prevents Enter from duplicating the automatic two factor challenge submission', function () {
|
||||
config(['app.maintenance.driver' => 'file']);
|
||||
|
||||
$user = createRootUser();
|
||||
$user->forceFill([
|
||||
'two_factor_secret' => Fortify::currentEncrypter()->encrypt('JBSWY3DPEHPK3PXP'),
|
||||
'two_factor_confirmed_at' => now(),
|
||||
])->save();
|
||||
|
||||
$page = visit('/login')
|
||||
->fill('email', 'test@example.com')
|
||||
->fill('password', 'password')
|
||||
->click('Login')
|
||||
->assertPathIs('/two-factor-challenge');
|
||||
|
||||
$page->script(<<<'JS'
|
||||
window.acceptedTwoFactorSubmissions = 0;
|
||||
|
||||
document.querySelector('form[action="/two-factor-challenge"]').addEventListener('submit', (event) => {
|
||||
if (!event.defaultPrevented) {
|
||||
window.acceptedTwoFactorSubmissions++;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
});
|
||||
JS);
|
||||
|
||||
foreach (str_split('123456') as $index => $digit) {
|
||||
$page->keys(sprintf('[aria-label="Digit %d"]', $index + 1), $digit);
|
||||
}
|
||||
|
||||
$page->keys('[aria-label="Digit 6"]', 'Enter')
|
||||
->assertScript('window.acceptedTwoFactorSubmissions', 1)
|
||||
->assertNoJavaScriptErrors()
|
||||
->screenshot(filename: 'login-two-factor-enter-single-submission');
|
||||
});
|
||||
|
||||
/**
|
||||
* Create the root user (id 0) with known credentials for browser login tests.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue