Skip to content

Commit ebda2c6

Browse files
committed
wip
1 parent 7f78d7e commit ebda2c6

File tree

5 files changed

+90
-6
lines changed

5 files changed

+90
-6
lines changed

app/Http/Controllers/Auth/AuthenticatedSessionController.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Illuminate\Support\Facades\Route;
1111
use Inertia\Inertia;
1212
use Inertia\Response;
13-
use Laravel\Fortify\Features;
13+
use Laravel\Fortify\Fortify;
1414

1515
class AuthenticatedSessionController extends Controller
1616
{
@@ -32,7 +32,7 @@ public function store(LoginRequest $request): RedirectResponse
3232
{
3333
$user = $request->validateCredentials();
3434

35-
if (Features::enabled(Features::twoFactorAuthentication()) && filled($user->two_factor_confirmed_at)) {
35+
if (Fortify::confirmsTwoFactorAuthentication() && filled($user->two_factor_confirmed_at)) {
3636
$request->session()->put([
3737
'login.id' => $user->getKey(),
3838
'login.remember' => $request->boolean('remember'),
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
namespace App\Http\Controllers\Concerns;
4+
5+
use Illuminate\Http\Request;
6+
use Illuminate\Support\Facades\Auth;
7+
use Laravel\Fortify\Actions\DisableTwoFactorAuthentication;
8+
use Laravel\Fortify\Features;
9+
10+
trait ConfirmsTwoFactorAuthentication
11+
{
12+
/**
13+
* Validate the two-factor authentication state for the request.
14+
*/
15+
protected function validateTwoFactorAuthenticationState(Request $request): void
16+
{
17+
if (! Features::optionEnabled(Features::twoFactorAuthentication(), 'confirm')) {
18+
return;
19+
}
20+
21+
$currentTime = time();
22+
23+
// Notate totally disabled state in session...
24+
if ($this->twoFactorAuthenticationDisabled($request)) {
25+
$request->session()->put('two_factor_empty_at', $currentTime);
26+
}
27+
28+
// If was previously totally disabled this session but is now confirming, notate time...
29+
if ($this->hasJustBegunConfirmingTwoFactorAuthentication($request)) {
30+
$request->session()->put('two_factor_confirming_at', $currentTime);
31+
}
32+
33+
// If the profile is reloaded and is not confirmed but was previously in confirming state, disable...
34+
if ($this->neverFinishedConfirmingTwoFactorAuthentication($request, $currentTime)) {
35+
app(DisableTwoFactorAuthentication::class)(Auth::user());
36+
37+
$request->session()->put('two_factor_empty_at', $currentTime);
38+
$request->session()->remove('two_factor_confirming_at');
39+
}
40+
}
41+
42+
/**
43+
* Determine if two-factor authentication is totally disabled.
44+
*/
45+
protected function twoFactorAuthenticationDisabled(Request $request): bool
46+
{
47+
return is_null($request->user()->two_factor_secret) &&
48+
is_null($request->user()->two_factor_confirmed_at);
49+
}
50+
51+
/**
52+
* Determine if two-factor authentication is just now being confirmed within the last request cycle.
53+
*/
54+
protected function hasJustBegunConfirmingTwoFactorAuthentication(Request $request): bool
55+
{
56+
return ! is_null($request->user()->two_factor_secret) &&
57+
is_null($request->user()->two_factor_confirmed_at) &&
58+
$request->session()->has('two_factor_empty_at') &&
59+
is_null($request->session()->get('two_factor_confirming_at'));
60+
}
61+
62+
/**
63+
* Determine if two-factor authentication was never totally confirmed once confirmation started.
64+
*/
65+
protected function neverFinishedConfirmingTwoFactorAuthentication(Request $request, int $currentTime): bool
66+
{
67+
return ! array_key_exists('code', $request->session()->getOldInput()) &&
68+
is_null($request->user()->two_factor_confirmed_at) &&
69+
$request->session()->get('two_factor_confirming_at', 0) != $currentTime;
70+
}
71+
}

app/Http/Controllers/Settings/TwoFactorAuthenticationController.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,19 @@
77
use Illuminate\Http\Request;
88
use Inertia\Inertia;
99
use Inertia\Response;
10+
use App\Http\Controllers\Concerns\ConfirmsTwoFactorAuthentication;
1011

1112
class TwoFactorAuthenticationController extends Controller
1213
{
14+
use ConfirmsTwoFactorAuthentication;
15+
1316
/**
1417
* Show the user's two-factor authentication settings page.
1518
*/
1619
public function show(Request $request): Response
1720
{
21+
$this->validateTwoFactorAuthenticationState($request);
22+
1823
/** @var User $user */
1924
$user = $request->user();
2025

app/Providers/FortifyServiceProvider.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@
1111

1212
class FortifyServiceProvider extends ServiceProvider
1313
{
14+
/**
15+
* Register any application services.
16+
*/
17+
public function register(): void
18+
{
19+
//
20+
}
21+
1422
/**
1523
* Bootstrap any application services.
1624
*/

resources/js/pages/settings/TwoFactor.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ const toggleRecoveryCodes = () => {
7777
<div class="space-y-6">
7878
<HeadingSmall title="Two-Factor Authentication" description="Manage your two-factor authentication settings" />
7979
<div v-if="!props.confirmed" class="flex flex-col items-start justify-start space-y-5">
80-
<Badge variant="outline" class="border-orange-200 bg-orange-50 text-orange-700 hover:bg-orange-50"> Disabled </Badge>
80+
<Badge variant="destructive"> Disabled </Badge>
8181
<p class="-translate-y-1 text-muted-foreground">
8282
When you enable 2FA, you'll be prompted for a secure code during login, which can be retrieved from your phone's TOTP
8383
supported app.
@@ -245,15 +245,15 @@ const toggleRecoveryCodes = () => {
245245
</div>
246246

247247
<div v-if="props.confirmed" class="flex flex-col items-start justify-start space-y-5">
248-
<Badge variant="outline" class="border-green-200 bg-green-50 text-green-700 hover:bg-green-50"> Enabled </Badge>
248+
<Badge variant="default"> Enabled </Badge>
249249
<p class="text-muted-foreground">
250250
With two factor authentication enabled, you'll be prompted for a secure, random token during login, which you can retrieve
251251
from your TOTP Authenticator app.
252252
</p>
253253

254254
<div>
255-
<div class="flex items-start rounded-t-xl border border-muted p-4">
256-
<LockKeyhole class="mr-2 size-5 text-stone-500" />
255+
<div class="flex items-start rounded-t-xl border border-secondary p-4">
256+
<LockKeyhole class="mr-2 size-5 text-muted-foreground" />
257257
<div class="space-y-1">
258258
<h3 class="font-medium">2FA Recovery Codes</h3>
259259
<p class="text-sm text-muted-foreground">

0 commit comments

Comments
 (0)