diff --git a/includes/auth_helper.php b/includes/auth_helper.php
index 539eee1..704e17f 100644
--- a/includes/auth_helper.php
+++ b/includes/auth_helper.php
@@ -1,14 +1,41 @@
0,
+ 'path' => '/',
+ 'domain' => '',
+ 'secure' => $secure,
+ 'httponly' => true,
+ 'samesite' => $samesite
+ ]);
+
+ if (!session_start()) {
+ error_log("Failed to start session");
+ }
+ }
+}
+
+start_secure_session();
/**
* Authentication Helper
*/
class Auth {
public static function isLoggedIn(): bool {
- return isset($_SESSION['user_id']);
+ return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
}
public static function requireLogin(): void {
@@ -19,42 +46,46 @@ class Auth {
}
public static function login(int $userId, int $tenantId, string $role): void {
+ if (session_status() === PHP_SESSION_NONE) {
+ start_secure_session();
+ }
+
$_SESSION['user_id'] = $userId;
$_SESSION['tenant_id'] = $tenantId;
$_SESSION['role'] = $role;
- // Ensure session is saved before any potential issues or redirects
+ // Important: Save session before geolocation which might be slow
session_write_close();
- // Re-open session if we need to write more later (unlikely here but good practice if we were to)
- session_start();
-
+
+ // Tracking
$ip = self::getIpAddress();
$country = self::getCountryFromIp($ip);
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? null;
try {
- // Record session
+ // Re-open to update tracking info in DB if we want,
+ // but we can just use a fresh DB connection
$stmt = db()->prepare("INSERT INTO user_sessions (user_id, ip_address, country, user_agent) VALUES (?, ?, ?, ?)");
$stmt->execute([$userId, $ip, $country, $userAgent]);
- // Update user
$stmt = db()->prepare("UPDATE users SET last_login_at = NOW(), last_login_ip = ? WHERE id = ?");
$stmt->execute([$ip, $userId]);
} catch (\Throwable $e) {
- // Log error but don't prevent login
error_log("Auth::login tracking error: " . $e->getMessage());
}
}
public static function logout(): void {
if (session_status() === PHP_SESSION_NONE) {
- session_start();
+ start_secure_session();
}
$_SESSION = [];
+ $params = session_get_cookie_params();
+ setcookie(session_name(), '', time() - 42000,
+ $params["path"], $params["domain"],
+ $params["secure"], $params["httponly"]
+ );
session_destroy();
- if (isset($_COOKIE[session_name()])) {
- setcookie(session_name(), '', time() - 42000, '/');
- }
header('Location: login.php', true, 302);
exit;
}
@@ -80,14 +111,14 @@ class Auth {
return $data['country'] ?? 'Unknown';
}
} catch (\Throwable $e) {
- // Ignore errors for geolocation
}
return 'Unknown';
}
public static function recordResetAttempt(string $email, string $ip): void {
- // We could log this to a separate table or activity_log
- $stmt = db()->prepare("INSERT INTO activity_log (tenant_id, action, details) VALUES (?, ?, ?)");
- $stmt->execute([0, 'Password Reset Attempt', "Email: $email, IP: $ip"]);
+ try {
+ $stmt = db()->prepare("INSERT INTO activity_log (tenant_id, action, details) VALUES (?, ?, ?)");
+ $stmt->execute([0, 'Password Reset Attempt', "Email: $email, IP: $ip"]);
+ } catch (\Throwable $e) {}
}
}
diff --git a/test_session.php b/test_session.php
new file mode 100644
index 0000000..1dacd6e
--- /dev/null
+++ b/test_session.php
@@ -0,0 +1,19 @@
+Session Diagnostic";
+echo "Counter: " . $_SESSION['test_counter'] . " (Refresh to see if it increases)
";
+echo "Session ID: " . session_id() . "
";
+echo "HTTPS: " . (isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : 'off') . "
";
+echo "SameSite: " . (session_get_cookie_params()['samesite'] ?? 'Not set') . "
";
+echo "
SameSite=None; Secure which should fix this, but some browsers require extra permissions or have strict privacy settings.";
+echo "