diff --git a/app/Http/Controllers/Auth/AuthenticatedSessionController.php b/app/Http/Controllers/Auth/AuthenticatedSessionController.php index 2f0199a..c85b1cc 100644 --- a/app/Http/Controllers/Auth/AuthenticatedSessionController.php +++ b/app/Http/Controllers/Auth/AuthenticatedSessionController.php @@ -35,8 +35,25 @@ class AuthenticatedSessionController extends Controller $user = Auth::user(); - // If user has 2FA enabled, redirect to challenge screen - if ($user->two_factor_confirmed_at && $user->two_factor_secret) { + // Check global 2FA toggles + $totpAllowed = true; + $emailAllowed = true; + try { + $settings = \Illuminate\Support\Facades\Cache::rememberForever('system_settings', function () { + return \App\Models\Setting::all()->pluck('value', 'key')->toArray(); + }); + if (isset($settings['two_factor_totp_enabled'])) { + $totpAllowed = $settings['two_factor_totp_enabled'] === '1' || $settings['two_factor_totp_enabled'] === true; + } + if (isset($settings['two_factor_email_enabled'])) { + $emailAllowed = $settings['two_factor_email_enabled'] === '1' || $settings['two_factor_email_enabled'] === true; + } + } catch (\Exception $e) { + // DB not ready or migrated + } + + // If user has 2FA enabled, and it's globally allowed, redirect to challenge screen + if ($totpAllowed && $user->two_factor_confirmed_at && $user->two_factor_secret) { $request->session()->put('two_factor_user_id', $user->id); $request->session()->put('two_factor_type', 'totp'); Auth::guard('web')->logout(); @@ -45,8 +62,8 @@ class AuthenticatedSessionController extends Controller return redirect()->route('two-factor.challenge'); } - // If user has Email 2FA enabled, redirect to email challenge - if ($user->email_2fa_enabled) { + // If user has Email 2FA enabled, and it's globally allowed, redirect to email challenge + if ($emailAllowed && $user->email_2fa_enabled) { $code = str_pad(mt_rand(100000, 999999), 6, '0', STR_PAD_LEFT); $user->update([ 'email_2fa_code' => $code, diff --git a/app/Http/Controllers/TwoFactorController.php b/app/Http/Controllers/TwoFactorController.php index 97421ef..5bbc735 100644 --- a/app/Http/Controllers/TwoFactorController.php +++ b/app/Http/Controllers/TwoFactorController.php @@ -56,11 +56,45 @@ class TwoFactorController extends Controller ]); } + private function isTotpAllowed(): bool + { + try { + $settings = \Illuminate\Support\Facades\Cache::rememberForever('system_settings', function () { + return \App\Models\Setting::all()->pluck('value', 'key')->toArray(); + }); + if (isset($settings['two_factor_totp_enabled'])) { + return $settings['two_factor_totp_enabled'] === '1' || $settings['two_factor_totp_enabled'] === true; + } + } catch (\Exception $e) { + // DB not ready or migrated + } + return true; + } + + private function isEmailAllowed(): bool + { + try { + $settings = \Illuminate\Support\Facades\Cache::rememberForever('system_settings', function () { + return \App\Models\Setting::all()->pluck('value', 'key')->toArray(); + }); + if (isset($settings['two_factor_email_enabled'])) { + return $settings['two_factor_email_enabled'] === '1' || $settings['two_factor_email_enabled'] === true; + } + } catch (\Exception $e) { + // DB not ready or migrated + } + return true; + } + /** * Confirm & enable 2FA. */ public function enable(Request $request) { + if (!$this->isTotpAllowed()) { + abort(403, 'Google Authenticator (TOTP) is globally disabled by the administrator.'); + } + $request->validate([ 'code' => 'required|string', ]); @@ -111,6 +145,10 @@ class TwoFactorController extends Controller 'enabled' => 'required|boolean', ]); + if ($request->enabled && !$this->isEmailAllowed()) { + abort(403, 'Email Two-Factor Authentication is globally disabled by the administrator.'); + } + $user = auth()->user(); if ($request->enabled) { // Live-verify SMTP configuration by sending a test validation email