fix: not being able to stay logged in
This commit is contained in:
parent
01ad3b6a58
commit
0b87dc3cac
4 changed files with 215 additions and 37 deletions
29
index.php
29
index.php
|
@ -33,19 +33,6 @@ spl_autoload_register(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* Session
|
|
||||||
*
|
|
||||||
* Has to be setup first, before anything else, so translations can be loaded.
|
|
||||||
*/
|
|
||||||
session_start(
|
|
||||||
array(
|
|
||||||
'name' => 'wishthis',
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$user = User::getCurrent();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config
|
* Config
|
||||||
*/
|
*/
|
||||||
|
@ -55,6 +42,22 @@ if (file_exists($configPath)) {
|
||||||
require $configPath;
|
require $configPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session
|
||||||
|
*
|
||||||
|
* Has to be setup first, before anything else, so translations can be loaded.
|
||||||
|
* The configuration is the only exception, since `loadFromSession` needs the
|
||||||
|
* database.
|
||||||
|
*/
|
||||||
|
session_start(
|
||||||
|
array(
|
||||||
|
'name' => 'wishthis',
|
||||||
|
'cookie_lifetime' => \ini_get('session.gc_maxlifetime') ?: 1440,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$user = User::getCurrent();
|
||||||
|
$user->loadFromSession();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database
|
* Database
|
||||||
|
|
|
@ -160,6 +160,10 @@ class Page
|
||||||
*/
|
*/
|
||||||
$user = User::getCurrent();
|
$user = User::getCurrent();
|
||||||
|
|
||||||
|
if ($user->isLoggedIn()) {
|
||||||
|
$user->refreshSession();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Login
|
* Login
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -45,9 +45,7 @@ class User
|
||||||
$_SESSION['user'] = new self();
|
$_SESSION['user'] = new self();
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = $_SESSION['user'];
|
return $_SESSION['user'];
|
||||||
|
|
||||||
return $user;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -159,6 +157,13 @@ class User
|
||||||
*/
|
*/
|
||||||
private bool $advertisements = false;
|
private bool $advertisements = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the user wants to stay logged in.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private bool $stayLoggedIn = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Non-Static
|
* Non-Static
|
||||||
*/
|
*/
|
||||||
|
@ -244,7 +249,38 @@ class User
|
||||||
*/
|
*/
|
||||||
public function isLoggedIn(): bool
|
public function isLoggedIn(): bool
|
||||||
{
|
{
|
||||||
return isset($this->id) && $this->id >= 1;
|
if (!isset($_COOKIE['wishthis'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$database = new Database(
|
||||||
|
DATABASE_HOST,
|
||||||
|
DATABASE_NAME,
|
||||||
|
DATABASE_USER,
|
||||||
|
DATABASE_PASSWORD
|
||||||
|
);
|
||||||
|
$database->connect();
|
||||||
|
|
||||||
|
$session = $database
|
||||||
|
->query(
|
||||||
|
'SELECT *
|
||||||
|
FROM `sessions`
|
||||||
|
WHERE `session` = :session',
|
||||||
|
array(
|
||||||
|
'session' => $_COOKIE['wishthis'],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->fetch();
|
||||||
|
|
||||||
|
if (false === $session) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\strtotime($session['expires']) <= \time()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -313,7 +349,7 @@ class User
|
||||||
*
|
*
|
||||||
* @return bool Whether the log in was successful.
|
* @return bool Whether the log in was successful.
|
||||||
*/
|
*/
|
||||||
public function logIn(string $email = '', string $password = '', bool $user_login_is_persistent = false): bool
|
public function logIn(string $email = '', string $password = '', bool $userLoginIsPersistent = false): bool
|
||||||
{
|
{
|
||||||
$database = new Database(
|
$database = new Database(
|
||||||
DATABASE_HOST,
|
DATABASE_HOST,
|
||||||
|
@ -344,7 +380,7 @@ class User
|
||||||
'user_password' => $password,
|
'user_password' => $password,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
->fetch();
|
->fetch(\PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetching the user fields has failed and we are now assuming that the
|
* Fetching the user fields has failed and we are now assuming that the
|
||||||
|
@ -368,30 +404,19 @@ class User
|
||||||
'user_password' => $password,
|
'user_password' => $password,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$user_database_fields['last_login'] = time();
|
$user_database_fields['last_login'] = date('Y-m-d H:i');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set session duration
|
* Set session duration
|
||||||
*/
|
*/
|
||||||
$database
|
$this->refreshSession($user_database_fields['id']);
|
||||||
->query(
|
|
||||||
'REPLACE INTO `sessions` (`user`, `session`, `expires`) VALUES (
|
|
||||||
:user_id,
|
|
||||||
:session_id,
|
|
||||||
:session_expires
|
|
||||||
)',
|
|
||||||
array(
|
|
||||||
'user_id' => $user_database_fields['id'],
|
|
||||||
'session_id' => \session_id(),
|
|
||||||
'session_expires' => date('Y-m-d H:i', time() + 1800),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a `User` object instance and assign it for later use.
|
* Create a `User` object instance and assign it for later use.
|
||||||
*/
|
*/
|
||||||
if (\is_array($user_database_fields)) {
|
if (\is_array($user_database_fields)) {
|
||||||
$this->__construct($user_database_fields);
|
$this->__construct($user_database_fields);
|
||||||
|
$this->stayLoggedIn = $userLoginIsPersistent;
|
||||||
|
|
||||||
$_SESSION['user'] = $this;
|
$_SESSION['user'] = $this;
|
||||||
|
|
||||||
|
@ -404,6 +429,22 @@ class User
|
||||||
public function logOut(): void
|
public function logOut(): void
|
||||||
{
|
{
|
||||||
/** Destroy session */
|
/** Destroy session */
|
||||||
|
$database = new Database(
|
||||||
|
DATABASE_HOST,
|
||||||
|
DATABASE_NAME,
|
||||||
|
DATABASE_USER,
|
||||||
|
DATABASE_PASSWORD
|
||||||
|
);
|
||||||
|
$database->connect();
|
||||||
|
$database
|
||||||
|
->query(
|
||||||
|
'DELETE FROM `sessions`
|
||||||
|
WHERE `session` = :session',
|
||||||
|
array(
|
||||||
|
'session' => $_COOKIE['wishthis'],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
session_destroy();
|
session_destroy();
|
||||||
unset($_SESSION);
|
unset($_SESSION);
|
||||||
}
|
}
|
||||||
|
@ -510,4 +551,133 @@ class User
|
||||||
{
|
{
|
||||||
return $this->password_reset_valid_until;
|
return $this->password_reset_valid_until;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function refreshSession(int $forUser = 0): void
|
||||||
|
{
|
||||||
|
$sessionId = $_COOKIE['wishthis'];
|
||||||
|
$sessionDurationSeconds = \ini_get('session.gc_maxlifetime') ?: 1440;
|
||||||
|
|
||||||
|
if ($this->stayLoggedIn) {
|
||||||
|
$sessionDurationSeconds = 31104000; // One year
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 === $forUser) {
|
||||||
|
$forUser = $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$database = new Database(
|
||||||
|
DATABASE_HOST,
|
||||||
|
DATABASE_NAME,
|
||||||
|
DATABASE_USER,
|
||||||
|
DATABASE_PASSWORD
|
||||||
|
);
|
||||||
|
$database->connect();
|
||||||
|
|
||||||
|
/** Delete outdated sessions */
|
||||||
|
$database
|
||||||
|
->query(
|
||||||
|
'DELETE FROM `sessions`
|
||||||
|
WHERE `expires` <= NOW()',
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Find existing session */
|
||||||
|
$sessionsExisting = $database
|
||||||
|
->query(
|
||||||
|
'SELECT *
|
||||||
|
FROM `sessions`
|
||||||
|
WHERE `session` = :session',
|
||||||
|
array(
|
||||||
|
'session' => $sessionId,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->fetchAll();
|
||||||
|
|
||||||
|
/** The session exists and can be updated now */
|
||||||
|
foreach ($sessionsExisting as $session) {
|
||||||
|
if ($session['session'] === $sessionId) {
|
||||||
|
$database
|
||||||
|
->query(
|
||||||
|
'UPDATE `sessions`
|
||||||
|
SET `expires` = :expires
|
||||||
|
WHERE `session` = :session
|
||||||
|
AND `user` = :user',
|
||||||
|
array(
|
||||||
|
'expires' => date('Y-m-d H:i', time() + $sessionDurationSeconds),
|
||||||
|
'session' => $sessionId,
|
||||||
|
'user' => $forUser,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/** There's no need to do anything further. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Since there has been no return until now, we are assuming the session
|
||||||
|
* does not exist and will create it now.
|
||||||
|
*/
|
||||||
|
$database
|
||||||
|
->query(
|
||||||
|
'INSERT INTO `sessions` (`user`, `session`, `expires`) VALUES (
|
||||||
|
:user_id,
|
||||||
|
:session_id,
|
||||||
|
:session_expires
|
||||||
|
)',
|
||||||
|
array(
|
||||||
|
'user_id' => $forUser,
|
||||||
|
'session_id' => $sessionId,
|
||||||
|
'session_expires' => date('Y-m-d H:i', time() + $sessionDurationSeconds),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadFromSession(): void
|
||||||
|
{
|
||||||
|
if (!$this->isLoggedIn()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$database = new Database(
|
||||||
|
DATABASE_HOST,
|
||||||
|
DATABASE_NAME,
|
||||||
|
DATABASE_USER,
|
||||||
|
DATABASE_PASSWORD
|
||||||
|
);
|
||||||
|
$database->connect();
|
||||||
|
|
||||||
|
$session = $database
|
||||||
|
->query(
|
||||||
|
'SELECT *
|
||||||
|
FROM `sessions`
|
||||||
|
WHERE `session` = :session
|
||||||
|
AND `user` = :user',
|
||||||
|
array(
|
||||||
|
'session' => $_COOKIE['wishthis'],
|
||||||
|
'user' => $this->id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->fetch(\PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (false === $session) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $database
|
||||||
|
->query(
|
||||||
|
'SELECT *
|
||||||
|
FROM `users`
|
||||||
|
WHERE `id` = :user',
|
||||||
|
array(
|
||||||
|
'user' => $this->id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->fetch(\PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (false === $user) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->__construct($user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,10 @@ $page = new Page(__FILE__, __('Login'));
|
||||||
if (isset($_POST['login'], $_POST['email'], $_POST['password'])) {
|
if (isset($_POST['login'], $_POST['email'], $_POST['password'])) {
|
||||||
$user_email = \filter_input(\INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
|
$user_email = \filter_input(\INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
|
||||||
$user_password = User::passwordToHash($_POST['password']);
|
$user_password = User::passwordToHash($_POST['password']);
|
||||||
$user_login_is_persistent = isset($_POST['persistent']);
|
$userLoginIsPersistent = isset($_POST['persistent']);
|
||||||
|
|
||||||
$user->login($user_email, $user_password, $user_login_is_persistent);
|
$user->login($user_email, $user_password, $userLoginIsPersistent);
|
||||||
|
$user = User::getCurrent();
|
||||||
|
|
||||||
if (!$user->isLoggedIn()) {
|
if (!$user->isLoggedIn()) {
|
||||||
$page->messages[] = Page::error(
|
$page->messages[] = Page::error(
|
||||||
|
|
Loading…
Reference in a new issue