login update

This commit is contained in:
Flatlogic Bot 2026-02-15 18:07:08 +00:00
parent 36b8744143
commit 9ff74420bd
2 changed files with 67 additions and 17 deletions

View File

@ -1,14 +1,41 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
session_start(); /**
* Configure session for iframed environments (like Flatlogic preview)
*/
function start_secure_session() {
if (session_status() === PHP_SESSION_NONE) {
$secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| ($_SERVER['SERVER_PORT'] == 443)
|| (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https');
// Use SameSite=None only if secure, otherwise use Lax
$samesite = $secure ? 'None' : 'Lax';
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '',
'secure' => $secure,
'httponly' => true,
'samesite' => $samesite
]);
if (!session_start()) {
error_log("Failed to start session");
}
}
}
start_secure_session();
/** /**
* Authentication Helper * Authentication Helper
*/ */
class Auth { class Auth {
public static function isLoggedIn(): bool { public static function isLoggedIn(): bool {
return isset($_SESSION['user_id']); return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
} }
public static function requireLogin(): void { public static function requireLogin(): void {
@ -19,42 +46,46 @@ class Auth {
} }
public static function login(int $userId, int $tenantId, string $role): void { 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['user_id'] = $userId;
$_SESSION['tenant_id'] = $tenantId; $_SESSION['tenant_id'] = $tenantId;
$_SESSION['role'] = $role; $_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(); 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(); $ip = self::getIpAddress();
$country = self::getCountryFromIp($ip); $country = self::getCountryFromIp($ip);
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? null; $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? null;
try { 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 = db()->prepare("INSERT INTO user_sessions (user_id, ip_address, country, user_agent) VALUES (?, ?, ?, ?)");
$stmt->execute([$userId, $ip, $country, $userAgent]); $stmt->execute([$userId, $ip, $country, $userAgent]);
// Update user
$stmt = db()->prepare("UPDATE users SET last_login_at = NOW(), last_login_ip = ? WHERE id = ?"); $stmt = db()->prepare("UPDATE users SET last_login_at = NOW(), last_login_ip = ? WHERE id = ?");
$stmt->execute([$ip, $userId]); $stmt->execute([$ip, $userId]);
} catch (\Throwable $e) { } catch (\Throwable $e) {
// Log error but don't prevent login
error_log("Auth::login tracking error: " . $e->getMessage()); error_log("Auth::login tracking error: " . $e->getMessage());
} }
} }
public static function logout(): void { public static function logout(): void {
if (session_status() === PHP_SESSION_NONE) { if (session_status() === PHP_SESSION_NONE) {
session_start(); start_secure_session();
} }
$_SESSION = []; $_SESSION = [];
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
session_destroy(); session_destroy();
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time() - 42000, '/');
}
header('Location: login.php', true, 302); header('Location: login.php', true, 302);
exit; exit;
} }
@ -80,14 +111,14 @@ class Auth {
return $data['country'] ?? 'Unknown'; return $data['country'] ?? 'Unknown';
} }
} catch (\Throwable $e) { } catch (\Throwable $e) {
// Ignore errors for geolocation
} }
return 'Unknown'; return 'Unknown';
} }
public static function recordResetAttempt(string $email, string $ip): void { public static function recordResetAttempt(string $email, string $ip): void {
// We could log this to a separate table or activity_log try {
$stmt = db()->prepare("INSERT INTO activity_log (tenant_id, action, details) VALUES (?, ?, ?)"); $stmt = db()->prepare("INSERT INTO activity_log (tenant_id, action, details) VALUES (?, ?, ?)");
$stmt->execute([0, 'Password Reset Attempt', "Email: $email, IP: $ip"]); $stmt->execute([0, 'Password Reset Attempt', "Email: $email, IP: $ip"]);
} catch (\Throwable $e) {}
} }
} }

19
test_session.php Normal file
View File

@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/includes/auth_helper.php';
if (!isset($_SESSION['test_counter'])) {
$_SESSION['test_counter'] = 0;
}
$_SESSION['test_counter']++;
echo "<h1>Session Diagnostic</h1>";
echo "<b>Counter:</b> " . $_SESSION['test_counter'] . " (Refresh to see if it increases)<br>";
echo "<b>Session ID:</b> " . session_id() . "<br>";
echo "<b>HTTPS:</b> " . (isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : 'off') . "<br>";
echo "<b>SameSite:</b> " . (session_get_cookie_params()['samesite'] ?? 'Not set') . "<br>";
echo "<hr>";
echo "<h3>If the counter doesn't increase on refresh:</h3>";
echo "Your browser is likely blocking the session cookie because the preview is in an iframe. ";
echo "I have set <code>SameSite=None; Secure</code> which should fix this, but some browsers require extra permissions or have strict privacy settings.";
echo "<br><br><a href='test_session.php'>Click here to Refresh</a>";
echo "<br><br><a href='login.php'>Go to Login</a>";