diff --git a/includes/User.class.php b/includes/User.class.php index e44464c..6e6a44e 100644 --- a/includes/User.class.php +++ b/includes/User.class.php @@ -10,6 +10,10 @@ class User { $this->username = $row['username']; } + public function destroySession(DatabaseHandle $conn, string $token) { + $conn->query('DELETE FROM user_sessions WHERE user_id = ? AND token = ?', [$this->user_id, $token]); + } + public static function findByUsername(DatabaseHandle $conn, string $username) : User | null { $query = $conn->query('SELECT id, username FROM users WHERE username = ?', [$username]); $row = $query->fetch(); @@ -35,13 +39,22 @@ class User { public static function createFromRememberToken(DatabaseHandle $conn, string $remember_token) : User | null { $result = $conn->query( - 'SELECT users.id AS id, users.username AS username, users.banned AS banned + 'SELECT users.id AS id, users.username AS username, users.banned AS banned, user_sessions.id AS session_id, user_sessions.expire_at AS session_expiry FROM user_sessions INNER JOIN users ON users.id = user_sessions.user_id WHERE user_sessions.token = ?', [$remember_token] ); if ($row = $result->fetch()) { + $session_expiry = new DateTime($row['session_expiry']); + $now = new DateTime(); + + /* Session is expired (diff is negative) */ + if ($now->diff($session_expiry)->invert === 1) { + $conn->query('DELETE FROM user_sessions WHERE id = ?', [$row['session_id']]); + return null; + } + return new User($row); } diff --git a/includes/common.php b/includes/common.php index 970858b..a1b649b 100644 --- a/includes/common.php +++ b/includes/common.php @@ -141,14 +141,6 @@ if (in_array($lang_file, scandir('langs/'))) { $ip = $_SERVER['REMOTE_ADDR']; if (is_banned($conn, $ip)) die($lang['banned']); // "You have been banned from ".$site_name; -// Logout -if (isset($_GET['logout'])) { - header('Location: ' . $_SERVER['HTTP_REFERER']); - unset($_SESSION['user_id']); - unset($_SESSION['pic']); - session_destroy(); -} - $site_ads = getSiteAds($conn); $total_pastes = getSiteTotalPastes($conn); $total_page_views = getSiteTotalviews($conn); diff --git a/login.php b/login.php index 8787db2..2380ec8 100644 --- a/login.php +++ b/login.php @@ -92,10 +92,12 @@ if (isset($_POST['forgot'])) { if ($remember_me) { $remember_token = pp_random_token(); + $expire_at = (new DateTime())->add(new DateInterval('P1Y')); - $conn->query('INSERT INTO user_sessions (user_id, token) VALUES (?, ?)', [$user_id, $remember_token]); + $conn->query('INSERT INTO user_sessions (user_id, token, expire_at) VALUES (?, ?, FROM_UNIXTIME(?))', [$user_id, $remember_token, $expire_at->format('U')]); setcookie(User::REMEMBER_TOKEN_COOKIE, $remember_token, [ + 'expires' => (int) $expire_at->format('U'), 'secure' => !empty($_SERVER['HTTPS']), /* Local dev environment is non-HTTPS */ 'httponly' => true, 'samesite' => 'Lax' diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..3fa5dfe --- /dev/null +++ b/logout.php @@ -0,0 +1,21 @@ +destroySession($conn, $_COOKIE[User::REMEMBER_TOKEN_COOKIE]); +unset($_COOKIE[User::REMEMBER_TOKEN_COOKIE]); +setcookie(User::REMEMBER_TOKEN_COOKIE, null, time() - 3600); + +/* Destroy PHP session */ +unset($_SESSION['user_id']); +session_destroy(); + +header('Location: ' . $_SERVER['HTTP_REFERER']); diff --git a/theme/bulma/header.php b/theme/bulma/header.php index 9c6652f..590e4c9 100644 --- a/theme/bulma/header.php +++ b/theme/bulma/header.php @@ -132,11 +132,11 @@ $start = $time; echo 'Pastes'; echo 'Settings'; } - echo '