125 lines
4.0 KiB
PHP
125 lines
4.0 KiB
PHP
<?php
|
|
/**
|
|
* Fociz Session Guard API (Release v1.6)
|
|
* Ondersteunt realtime session keepalive, inactiviteitstimeout status en veilige logout
|
|
* Conform NIST SP 800-63B, OWASP ASVS v4.0 en ISO 27001
|
|
*/
|
|
|
|
require_once __DIR__ . '/../includes/auth.php';
|
|
require_once __DIR__ . '/../includes/settings.php';
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
$currentUser = require_auth(true);
|
|
$userId = (int)($currentUser['id'] ?? 0);
|
|
|
|
$action = $_GET['action'] ?? ($_POST['action'] ?? 'keepalive');
|
|
$idleTimeout = get_session_idle_timeout();
|
|
$now = time();
|
|
|
|
if ($action === 'keepalive' || $action === 'ping') {
|
|
// Verleng de activiteitstimer van de sessie
|
|
$_SESSION['last_activity'] = $now;
|
|
$_SESSION['last_db_activity_update'] = $now;
|
|
try {
|
|
$db = get_db_connection();
|
|
$stmtAct = $db->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;
|
|
|