Add persistent session option

This commit is contained in:
grandeljay 2022-09-30 15:41:07 +02:00
parent bcbad9e80a
commit 4416492dda
9 changed files with 137 additions and 35 deletions

View file

@ -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
*/

View file

@ -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;

5
src/assets/js/login.js Normal file
View file

@ -0,0 +1,5 @@
$(function() {
$('.ui.checkbox').checkbox();
});

View file

@ -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());
}
}

View file

@ -0,0 +1,20 @@
<?php
/**
* Get cookie domain
*/
function getCookieDomain(): string {
$cookieDomain = $_SERVER['HTTP_HOST'];
if (defined('CHANNELS') && is_iterable(CHANNELS) && defined('ENV_IS_DEV') && ! ENV_IS_DEV) {
foreach (CHANNELS as $channel) {
if ('stable' === $channel['branch']) {
$cookieDomain = $channel['host'];
break;
}
}
}
return '.' . $cookieDomain;
}

View file

@ -21,6 +21,7 @@ $step = isset($_POST['step']) ? $_POST['step'] : 1;
switch ($step) {
case 1:
session_destroy();
unset($_SESSION);
?>
<main>
<div class="ui hidden divider"></div>

View file

@ -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();
</div>
</div>
<input class="ui primary button"
type="submit"
name="login"
value="<?= __('Login') ?>"
title="<?= __('Login') ?>"
/>
<a class="ui tertiary button"
href="<?= Page::PAGE_REGISTER ?>"
title="<?= __('Register') ?>"
>
<?= __('Register') ?>
</a>
<div class="field">
<div class="ui toggle checkbox">
<input type="checkbox" name="persistent">
<label><?= __('Keep me logged in') ?></label>
</div>
</div>
<div class="inline fields">
<div class="field">
<input class="ui primary button"
type="submit"
name="login"
value="<?= __('Login') ?>"
title="<?= __('Login') ?>"
/>
</div>
<div class="field">
<a class="ui tertiary button"
href="<?= Page::PAGE_REGISTER ?>"
title="<?= __('Register') ?>"
>
<?= __('Register') ?>
</a>
</div>
</div>
</form>
</div>

View file

@ -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();

View file

@ -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.'),