From 4416492dda34078f037b6a9bcd7bdc022e918979 Mon Sep 17 00:00:00 2001 From: grandeljay Date: Fri, 30 Sep 2022 15:41:07 +0200 Subject: [PATCH] Add persistent session option --- index.php | 37 +++++++++-------- src/assets/css/default/dark.css | 13 +++++- src/assets/js/login.js | 5 +++ src/classes/user.php | 20 +++++++++ src/functions/getCookieDomain.php | 20 +++++++++ src/pages/install.php | 1 + src/pages/login.php | 69 +++++++++++++++++++++++++------ src/pages/logout.php | 6 +-- src/pages/profile.php | 1 + 9 files changed, 137 insertions(+), 35 deletions(-) create mode 100644 src/assets/js/login.js create mode 100644 src/functions/getCookieDomain.php diff --git a/index.php b/index.php index 2088d502..72cf4edc 100644 --- a/index.php +++ b/index.php @@ -11,6 +11,7 @@ namespace wishthis; define('VERSION', '0.7.0'); define('ROOT', __DIR__); define('DEFAULT_LOCALE', 'en_GB'); +define('COOKIE_PERSISTENT', 'wishthis_persistent'); /** * Include @@ -49,26 +50,9 @@ if (file_exists($configPath)) { /** * Session */ -$cookie_domain = $_SERVER['HTTP_HOST']; - -if (defined('CHANNELS') && is_iterable(CHANNELS) && defined('ENV_IS_DEV') && ! ENV_IS_DEV) { - foreach (CHANNELS as $channel) { - if ('stable' === $channel['branch']) { - $cookie_domain = $channel['host']; - - break; - } - } -} - -$sessionLifetime = 2592000 * 12; // 12 Months - session_start( array( - 'name' => 'wishthis', - 'cookie_lifetime' => $sessionLifetime, - 'cookie_path' => '/', - 'cookie_domain' => '.' . $cookie_domain, + 'name' => 'wishthis', ) ); @@ -102,6 +86,23 @@ if ( $options = new Options($database); } +/** + * Persistent (stay logged in) + */ +if (isset($_COOKIE[COOKIE_PERSISTENT])) { + $persistent = $database + ->query( + 'SELECT * + FROM `sessions` + WHERE `session` = "' . $_COOKIE[COOKIE_PERSISTENT] . '";' + ) + ->fetch(); + + if (false !== $persistent) { + $_SESSION['user'] = User::getFromID($persistent['user']); + } +} + /** * Language */ diff --git a/src/assets/css/default/dark.css b/src/assets/css/default/dark.css index f21c8773..79c2f86d 100644 --- a/src/assets/css/default/dark.css +++ b/src/assets/css/default/dark.css @@ -398,12 +398,23 @@ color: rgba(255, 255, 255, 0.95); } + /** Toggle */ + .ui.toggle.checkbox label { + color: rgba(255, 255, 255, 0.87); + } + .ui.toggle.checkbox label::before { + background: rgba(255, 255, 255, 0.05); + } + .ui.toggle.checkbox label:hover::before { + background-color: rgba(255, 255, 255, 0.15); + } + /** Calendar */ .ui.ui.table td.active, .ui.ui.ui.ui.table tr.active { color: rgba(255, 255, 255, 0.87); background-color: #1f1f1f; - box-shadow: 0 0 0 rgba(255, 255, 255, 0.87) inset; + box-shadow: rgba(123, 105, 105, 0.05) 255, 255, 0.87) inset; } .ui.bottom.popup::before { background-color: #000; diff --git a/src/assets/js/login.js b/src/assets/js/login.js new file mode 100644 index 00000000..0bd456c3 --- /dev/null +++ b/src/assets/js/login.js @@ -0,0 +1,5 @@ +$(function() { + + $('.ui.checkbox').checkbox(); + +}); diff --git a/src/classes/user.php b/src/classes/user.php index 042f71bd..5e6939d8 100644 --- a/src/classes/user.php +++ b/src/classes/user.php @@ -155,4 +155,24 @@ class User ?: $this->name_first ?: $this->email; } + + public function logOut(): void + { + /** Destroy session */ + if (isset($_COOKIE[COOKIE_PERSISTENT])) { + global $database; + + $persistent = $database + ->query( + 'DELETE FROM `sessions` + WHERE `session` = "' . $_COOKIE[COOKIE_PERSISTENT] . '";' + ); + } + + session_destroy(); + unset($_SESSION); + + /** Delete cookie */ + setcookie(COOKIE_PERSISTENT, '', time() - 3600, '/', getCookieDomain()); + } } diff --git a/src/functions/getCookieDomain.php b/src/functions/getCookieDomain.php new file mode 100644 index 00000000..9a77d3dd --- /dev/null +++ b/src/functions/getCookieDomain.php @@ -0,0 +1,20 @@ +
diff --git a/src/pages/login.php b/src/pages/login.php index fbc0e991..3d02ab12 100644 --- a/src/pages/login.php +++ b/src/pages/login.php @@ -39,6 +39,37 @@ if (isset($_POST['login'], $_POST['email'], $_POST['password'])) { $fields = $userQuery->fetch(); $_SESSION['user'] = new User($fields); + + /** + * Persisent session + */ + if (isset($_POST['persistent'])) { + /** Cookie options */ + $sessionPassword = md5(time() . rand(-2147483648, 2147483647)); + $sessionLifetime = 2592000 * 4; // 4 Months + $sessionIsDev = defined('ENV_IS_DEV') && ENV_IS_DEV; + $sessionOptions = array ( + 'domain' => getCookieDomain(), + 'expires' => time() + $sessionLifetime, + 'httponly' => true, + 'path' => '/', + 'samesite' => 'None', + 'secure' => !$sessionIsDev, + ); + + /** Set cookie */ + setcookie(COOKIE_PERSISTENT, $sessionPassword, $sessionOptions); + + $database->query( + 'INSERT INTO `sessions` ( + `user`, + `session` + ) VALUES ( + ' . $_SESSION['user']->id . ', + "' . $sessionPassword . '" + );' + ); + } } else { $page->messages[] = Page::error( __('No user could be found with the credentials you provided.'), @@ -144,18 +175,32 @@ $page->navigation(); - - - - +
+
+ + +
+
+ +
+
+ +
+ +
+ + + +
+
diff --git a/src/pages/logout.php b/src/pages/logout.php index a4c1cda5..23a78611 100644 --- a/src/pages/logout.php +++ b/src/pages/logout.php @@ -10,11 +10,9 @@ namespace wishthis; $page = new Page(__FILE__, __('Logout')); -if (PHP_SESSION_ACTIVE === session_status()) { - session_destroy(); +$_SESSION['user']->logOut(); - redirect(Page::PAGE_HOME); -} +redirect(Page::PAGE_HOME); $page->header(); $page->bodyStart(); diff --git a/src/pages/profile.php b/src/pages/profile.php index 9e987511..3412eeb6 100644 --- a/src/pages/profile.php +++ b/src/pages/profile.php @@ -124,6 +124,7 @@ if (isset($_POST['user-id'], $_POST['section'])) { if ($loginRequired) { session_destroy(); + unset($_SESSION); $page->messages[] = Page::warning( __('It is required for you to login again.'),