ip().':'.$login; if (RateLimiter::tooManyAttempts($throttleKey, 5)) { throw ValidationException::withMessages([ 'login' => 'Too many login attempts. Please try again in a minute.', ]); } $user = User::where('email', $login)->orWhere('username', $login)->first(); if (! $user || ! Hash::check($password, $user->password)) { RateLimiter::hit($throttleKey, 60); // Generic message on purpose — never reveal whether the login // identifier itself exists (no user enumeration). throw ValidationException::withMessages([ 'login' => 'These credentials do not match our records.', ]); } RateLimiter::clear($throttleKey); if ($user->two_factor_enabled) { $challengeToken = Str::random(40); Cache::put("2fa_challenge:{$challengeToken}", [ 'user_id' => $user->id, 'ip' => $request->ip(), 'attempts' => 0, ], now()->addMinutes(5)); return ['status' => 'requires_2fa', 'challenge_token' => $challengeToken]; } Auth::login($user); $request->session()->regenerate(); return ['status' => 'authenticated', 'user' => $user]; } }