1515class TwoFactorAuthController extends Controller
1616{
1717 /**
18- * Show the two factor authentication settings form.
18+ * Show the two factor auth settings page
19+ * route[GET] => 'settings/two-factor'
1920 *
2021 * @param \Illuminate\Http\Request $request
2122 * @return \Inertia\Response
@@ -24,15 +25,21 @@ public function show(Request $request)
2425 {
2526 $ user = $ request ->user ();
2627 $ confirmed = !is_null ($ user ->two_factor_confirmed_at );
27-
28+
29+ // If 2fa is not confirmed, we want to clear out secret and recovery codes
30+ if (!$ confirmed ) {
31+ app (DisableTwoFactorAuthentication::class)($ user );
32+ }
33+
2834 return Inertia::render ('settings/two-factor ' , [
2935 'confirmed ' => $ confirmed ,
3036 'recoveryCodes ' => $ this ->getRecoveryCodes ($ user ),
3137 ]);
3238 }
3339
3440 /**
35- * Enable two factor authentication for the user.
41+ * Enable two factor authentication
42+ * route[POST] => 'settings/two-factor'
3643 *
3744 * @param \Illuminate\Http\Request $request
3845 * @return \Illuminate\Http\JsonResponse
@@ -41,51 +48,22 @@ public function enable(Request $request)
4148 {
4249 [$ qrCode , $ secret ] = app (GenerateQrCodeAndSecretKey::class)($ request ->user ());
4350
44- $ recoveryCodes = $ this ->generateRecoveryCodes ($ request ->user ());
45-
4651 $ request ->user ()->forceFill ([
47- 'two_factor_secret ' => encrypt ($ secret ),
48- 'two_factor_recovery_codes ' => encrypt (json_encode ($ recoveryCodes ))
52+ 'two_factor_secret ' => encrypt ($ secret )
4953 ])->save ();
50-
54+
5155 return response ()->json ([
52- 'status ' => 'two-factor-authentication-enabled ' ,
53- 'svg ' => $ qrCode ,
54- 'secret ' => $ secret ,
55- 'recovery_codes ' => $ recoveryCodes
56+ 'qrCode ' => $ qrCode ,
57+ 'secret ' => $ secret
5658 ]);
5759 }
58-
59- /**
60- * Generate recovery codes for the user.
61- *
62- * @param \App\Models\User $user
63- * @return array
64- */
65- private function generateRecoveryCodes ($ user )
66- {
67- return app (GenerateNewRecoveryCodes::class)($ user );
68- }
69-
70- /**
71- * Disable two factor authentication for the user.
72- *
73- * @param \Illuminate\Http\Request $request
74- * @return \Illuminate\Http\RedirectResponse
75- */
76- public function disable (Request $ request )
77- {
78- $ disableTwoFactorAuthentication = app (DisableTwoFactorAuthentication::class);
79- $ disableTwoFactorAuthentication ($ request ->user ());
80-
81- return back ()->with ('status ' , 'two-factor-authentication-disabled ' );
82- }
8360
8461 /**
8562 * Verify and confirm the user's two-factor authentication.
63+ * route[POST] => 'settings/two-factor/confirm'
8664 *
8765 * @param \Illuminate\Http\Request $request
88- * @return \Illuminate\Http\RedirectResponse
66+ * @return \Illuminate\Http\JsonResponse
8967 */
9068 public function confirm (Request $ request )
9169 {
@@ -100,14 +78,60 @@ public function confirm(Request $request)
10078 $ valid = app (VerifyTwoFactorCode::class)($ secret , $ request ->code );
10179
10280 if ($ valid ) {
81+ // Generate recovery codes when confirming 2FA
82+ $ recoveryCodes = app (GenerateNewRecoveryCodes::class)($ request ->user ());
83+
84+ // Update user with recovery codes and confirm 2FA
85+ $ request ->user ()->forceFill ([
86+ 'two_factor_recovery_codes ' => encrypt (json_encode ($ recoveryCodes ))
87+ ])->save ();
88+
10389 app (ConfirmTwoFactorAuthentication::class)($ request ->user ());
104- return back ()->with ('status ' , 'two-factor-authentication-confirmed ' );
90+
91+ return response ()->json ([
92+ 'status ' => 'two-factor-authentication-confirmed ' ,
93+ 'recovery_codes ' => $ recoveryCodes
94+ ]);
10595 }
10696
97+ return response ()->json ([
98+ 'status ' => 'error ' ,
99+ 'message ' => 'The provided two-factor authentication code was invalid. '
100+ ], 422 );
101+ }
107102
108- return back ()->withErrors (['code ' => 'The provided two-factor authentication code was invalid. ' ]);
103+ /**
104+ * Generate new recovery codes for the user.
105+ * route[POST] => 'settings/two-factor/recovery-codes'
106+ *
107+ * @param \Illuminate\Http\Request $request
108+ * @return \Illuminate\Http\JsonResponse
109+ */
110+ public function regenerateRecoveryCodes (Request $ request )
111+ {
112+ $ codes = app (GenerateNewRecoveryCodes::class)($ request ->user ());
113+
114+ $ request ->user ()->forceFill ([
115+ 'two_factor_recovery_codes ' => encrypt (json_encode ($ codes ))
116+ ])->save ();
117+
118+ return response ()->json ([
119+ 'recovery_codes ' => $ codes
120+ ]);
109121 }
110122
123+ /**
124+ * Disable two factor authentication for the user.
125+ * route[DELETE] => 'settings/two-factor'
126+ *
127+ * @param \Illuminate\Http\Request $request
128+ * @return void
129+ */
130+ public function disable (Request $ request )
131+ {
132+ $ disableTwoFactorAuthentication = app (DisableTwoFactorAuthentication::class);
133+ $ disableTwoFactorAuthentication ($ request ->user ());
134+ }
111135
112136 /**
113137 * Get the recovery codes for the user.
@@ -143,29 +167,4 @@ private function getRecoveryCodes($user)
143167 ? json_decode (decrypt ($ user ->two_factor_recovery_codes ))
144168 : [];
145169 }
146-
147- /**
148- * Generate new recovery codes for the user.
149- *
150- * @param \Illuminate\Http\Request $request
151- * @return \Illuminate\Http\Response
152- */
153- public function regenerateRecoveryCodes (Request $ request )
154- {
155- $ codes = app (GenerateNewRecoveryCodes::class)($ request ->user ());
156-
157- $ request ->user ()->forceFill ([
158- 'two_factor_recovery_codes ' => encrypt (json_encode ($ codes ))
159- ])->save ();
160-
161- // Check if this is an AJAX request
162- if ($ request ->wantsJson () || $ request ->ajax ()) {
163- return response ()->json ([
164- 'status ' => 'recovery-codes-generated ' ,
165- 'recovery_codes ' => $ codes
166- ]);
167- }
168-
169- return back ()->with ('status ' , 'recovery-codes-generated ' );
170- }
171170}
0 commit comments