107 lines
3.4 KiB
PHP
107 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use Closure;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Config;
|
|
|
|
/**
|
|
* Profile-Based Session Timeout Middleware
|
|
*
|
|
* Enforces session timeouts based on the active profile type from platform configuration.
|
|
* This overrides the default SESSION_LIFETIME from .env with profile-specific timeouts.
|
|
*
|
|
* Configuration: config/timebank_cc.php -> 'profile_timeouts'
|
|
*/
|
|
class ProfileSessionTimeout
|
|
{
|
|
/**
|
|
* Handle an incoming request.
|
|
*
|
|
* @param \Illuminate\Http\Request $request
|
|
* @param \Closure $next
|
|
* @return mixed
|
|
*/
|
|
public function handle(Request $request, Closure $next)
|
|
{
|
|
// Skip timeout check for guests
|
|
if (!Auth::check()) {
|
|
return $next($request);
|
|
}
|
|
|
|
// Get active profile from session
|
|
$activeProfileType = session('activeProfileType');
|
|
$activeProfileId = session('activeProfileId');
|
|
|
|
// Get profile-specific timeout from config
|
|
$timeoutMinutes = $this->getProfileTimeout($activeProfileType);
|
|
|
|
// Get last activity timestamp
|
|
$lastActivity = session('last_activity_at');
|
|
|
|
// If this is the first request, set last activity and continue
|
|
if (!$lastActivity) {
|
|
session(['last_activity_at' => now()->timestamp]);
|
|
return $next($request);
|
|
}
|
|
|
|
// Calculate idle time in minutes
|
|
$idleMinutes = (now()->timestamp - $lastActivity) / 60;
|
|
|
|
// Check if session has timed out
|
|
if ($idleMinutes > $timeoutMinutes) {
|
|
// Log the timeout for debugging
|
|
\Log::info('Session timeout', [
|
|
'user_id' => Auth::id(),
|
|
'profile_type' => $activeProfileType,
|
|
'profile_id' => $activeProfileId,
|
|
'idle_minutes' => round($idleMinutes, 2),
|
|
'timeout_limit' => $timeoutMinutes,
|
|
]);
|
|
|
|
// Clear session and logout
|
|
Auth::logout();
|
|
$request->session()->invalidate();
|
|
$request->session()->regenerateToken();
|
|
|
|
// Redirect to login with timeout message
|
|
return redirect()->route('login')
|
|
->with('status', __('Your session has expired due to inactivity. Please log in again.'));
|
|
}
|
|
|
|
// Update last activity timestamp
|
|
session(['last_activity_at' => now()->timestamp]);
|
|
|
|
return $next($request);
|
|
}
|
|
|
|
/**
|
|
* Get the timeout duration in minutes for the given profile type
|
|
*
|
|
* @param string|null $profileType
|
|
* @return int Timeout in minutes
|
|
*/
|
|
protected function getProfileTimeout(?string $profileType): int
|
|
{
|
|
// Get profile_timeouts from platform config
|
|
$profileTimeouts = timebank_config('profile_timeouts', []);
|
|
|
|
// If profile type is set and has a specific timeout, use it
|
|
if ($profileType && isset($profileTimeouts[$profileType])) {
|
|
return (int) $profileTimeouts[$profileType];
|
|
}
|
|
|
|
// Otherwise, use the default timeout from platform config
|
|
$defaultTimeout = timebank_config('profile_timeout_default', 120);
|
|
|
|
// If still not set, fall back to SESSION_LIFETIME from .env
|
|
if (!$defaultTimeout) {
|
|
$defaultTimeout = Config::get('session.lifetime', 120);
|
|
}
|
|
|
|
return (int) $defaultTimeout;
|
|
}
|
|
}
|