Files
biiproject-kit-v1/app/Http/Controllers/Auth/AuthenticatedSessionController.php

129 lines
4.1 KiB
PHP

<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Models\User;
use App\Models\UserTrustedDevice;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
class AuthenticatedSessionController extends Controller
{
/**
* Display the login view
*/
public function create(): View
{
return view('auth.login');
}
/**
* Handle an incoming authentication request
*/
public function store(LoginRequest $request): RedirectResponse
{
// Batch common auth settings
$settings = [
'2fa_enabled' => get_setting('two_factor_auth', false),
'allow_remember' => get_setting('session_allow_remember_me', true),
'remember_duration' => get_setting('session_remember_me_duration', 30),
'single_session' => get_setting('session_single_session', false),
];
$credentials = $request->only('email', 'password');
$remember = $settings['allow_remember'] && $request->boolean('remember');
// Check if 2FA is enabled globally
if ($settings['2fa_enabled']) {
if (Auth::validate($credentials)) {
$user = User::where('email', $request->email)->first();
// Check Trust Device bypass (Secure check)
$cookieValue = $request->cookie('2fa_trust_device');
$trustedBypass = false;
if ($cookieValue && str_contains($cookieValue, '|')) {
$parts = explode('|', $cookieValue, 2);
if (count($parts) === 2 && ! empty($parts[0]) && ! empty($parts[1])) {
[$uuid, $secret] = $parts;
$trust = UserTrustedDevice::where('user_id', $user->id)
->where('device_id', $uuid)
->where('expires_at', '>', now())
->first();
if ($trust && hash_equals($trust->token, hash('sha256', $secret))) {
$trustedBypass = true;
}
}
}
if ($trustedBypass) {
Auth::attempt($credentials, $remember);
$request->session()->regenerate();
$user->update(['last_session_id' => session()->getId()]);
return redirect()->intended(route('dashboard', absolute: false));
}
// Generate & Send OTP
TwoFactorController::generateAndSendOtp($user);
session(['auth.2fa_remember' => $remember]);
return redirect()->route('2fa.index');
}
}
// Authenticate user credentials normally
$request->authenticate();
$request->session()->regenerate();
/** @var User $user */
$user = Auth::user();
$user->update(['last_session_id' => session()->getId()]);
// Custom duration Remember Me
if ($remember) {
$minutes = 60 * 24 * $settings['remember_duration'];
cookie()->queue(
cookie(
name: Auth::getRecallerName(),
value: cookie()->get(Auth::getRecallerName()),
minutes: $minutes,
httpOnly: true,
secure: app()->environment('production'),
)
);
}
// SINGLE SESSION ENFORCEMENT
if ($settings['single_session']) {
Auth::logoutOtherDevices($request->password);
}
return redirect()->intended('/dashboard');
}
/**
* Destroy an authenticated session
*/
public function destroy(Request $request): RedirectResponse
{
Auth::guard('web')->logout();
// Invalidate session for security
$request->session()->invalidate();
// Regenerate CSRF token
$request->session()->regenerateToken();
// Redirect to homepage
return redirect('/');
}
}