prepare("UPDATE users SET last_activity_at = NOW() WHERE id = ?"); $stmtAct->execute([$userId]); } catch (Throwable $e) {} echo json_encode([ 'success' => true, 'remaining' => $idleTimeout, 'timeout' => $idleTimeout, 'timestamp' => $now ], JSON_UNESCAPED_UNICODE); exit; } if ($action === 'status') { $lastActivity = (int)($_SESSION['last_activity'] ?? $now); $elapsed = $now - $lastActivity; $remaining = max(0, $idleTimeout - $elapsed); echo json_encode([ 'success' => true, 'remaining' => $remaining, 'timeout' => $idleTimeout, 'timestamp' => $now ], JSON_UNESCAPED_UNICODE); exit; } if ($action === 'logout') { try { $db = get_db_connection(); $stmt = $db->prepare("UPDATE users SET remember_token = NULL, remember_token_expires_at = NULL WHERE id = ?"); $stmt->execute([$userId]); fociz_terminate_session(session_id()); fociz_log_audit($userId, 'LOGOUT_SESSION_GUARD', 'users', $userId, ['ip' => fociz_get_client_ip()], 'SUCCESS', $currentUser['email'] ?? null); } catch (Throwable $e) { error_log("Session guard logout error: " . $e->getMessage()); } clear_day_session_cookie(); $_SESSION = []; if (session_status() === PHP_SESSION_ACTIVE) { @session_regenerate_id(true); @session_destroy(); } echo json_encode(['success' => true, 'message' => 'Succesvol uitgelogd.'], JSON_UNESCAPED_UNICODE); exit; } // Haal actieve apparaten en sessies op (SOC 2 CC6.1 / ISO 27001 A.9.4.2) if ($action === 'get_active_sessions') { $sessions = fociz_get_user_active_sessions($userId, session_id()); echo json_encode([ 'success' => true, 'sessions' => $sessions, 'timestamp' => $now ], JSON_UNESCAPED_UNICODE); exit; } // Beëindig alle overige actieve sessies (SOC 2 CC6.1) if ($action === 'revoke_other_sessions') { if (!verify_csrf_token($_POST['csrf_token'] ?? null)) { http_response_code(403); echo json_encode(['success' => false, 'error' => 'Ongeldig CSRF beveiligingstoken.'], JSON_UNESCAPED_UNICODE); exit; } $count = fociz_revoke_other_sessions($userId, session_id()); echo json_encode([ 'success' => true, 'revoked_count' => $count, 'message' => "Succesvol {$count} andere actieve sessie(s) op afstand beëindigd." ], JSON_UNESCAPED_UNICODE); exit; } // Beëindig specifieke sessie op afstand if ($action === 'revoke_session') { if (!verify_csrf_token($_POST['csrf_token'] ?? null)) { http_response_code(403); echo json_encode(['success' => false, 'error' => 'Ongeldig CSRF beveiligingstoken.'], JSON_UNESCAPED_UNICODE); exit; } $sessionDbId = (int)($_POST['session_id'] ?? 0); $ok = fociz_revoke_session_by_id($userId, $sessionDbId); echo json_encode([ 'success' => $ok, 'message' => $ok ? 'Sessie succesvol op afstand beëindigd.' : 'Kan sessie niet intrekken.' ], JSON_UNESCAPED_UNICODE); exit; } http_response_code(400); echo json_encode(['success' => false, 'error' => 'Onbekende sessieactie.'], JSON_UNESCAPED_UNICODE); exit;