feat: Enhance user logout and remember me functionality with secure cookie handling

This commit is contained in:
2026-02-26 22:36:56 +01:00
parent a4a35c8d62
commit 66d04faaa5
4 changed files with 302 additions and 103 deletions

View File

@@ -52,9 +52,9 @@
},
"class.S.php": {
"type": "-",
"size": 7575,
"size": 7988,
"lmtime": 0,
"modified": false
"modified": true
},
"class.Tpl.php": {
"type": "-",
@@ -83,14 +83,14 @@
},
"TasksController.php": {
"type": "-",
"size": 3009,
"size": 3109,
"lmtime": 0,
"modified": false
"modified": true
},
"UsersController.php": {
"type": "-",
"size": 10771,
"lmtime": 1772109739886,
"size": 13159,
"lmtime": 1772131160725,
"modified": false
}
},
@@ -121,15 +121,15 @@
},
"class.Tasks.php": {
"type": "-",
"size": 25433,
"size": 25767,
"lmtime": 1771495209476,
"modified": false
"modified": true
},
"class.Users.php": {
"type": "-",
"size": 4242,
"size": 4291,
"lmtime": 1770653518273,
"modified": false
"modified": true
},
"class.Wiki.php": {
"type": "-",
@@ -176,17 +176,23 @@
},
"WorkTimeRepository.php": {
"type": "-",
"size": 3269,
"size": 3394,
"lmtime": 0,
"modified": false
"modified": true
}
},
"Users": {
"PermissionRepository.php": {
"type": "-",
"size": 1656,
"lmtime": 1772131139905,
"modified": false
},
"UserRepository.php": {
"type": "-",
"size": 610,
"size": 643,
"lmtime": 1770653480229,
"modified": false
"modified": true
},
"VacationRepository.php": {
"type": "-",
@@ -223,9 +229,9 @@
},
"class.Projects.php": {
"type": "-",
"size": 27476,
"size": 27485,
"lmtime": 0,
"modified": false
"modified": true
},
"class.Tasks.php": {
"type": "-",
@@ -246,7 +252,32 @@
"modified": false
}
},
"view": {}
"view": {
"class.Cron.php": {
"type": "-",
"size": 164,
"lmtime": 0,
"modified": false
},
"class.Projects.php": {
"type": "-",
"size": 46,
"lmtime": 0,
"modified": false
},
"class.Site.php": {
"type": "-",
"size": 1014,
"lmtime": 0,
"modified": false
},
"class.Users.php": {
"type": "-",
"size": 361,
"lmtime": 0,
"modified": false
}
}
},
"ceidg.php": {
"type": "-",
@@ -283,13 +314,13 @@
".htaccess": {
"type": "-",
"size": 1055,
"lmtime": 0,
"modified": true
"lmtime": 1772103779000,
"modified": false
},
"index.php": {
"type": "-",
"size": 2782,
"lmtime": 1772108635118,
"size": 3592,
"lmtime": 1772131174733,
"modified": false
},
"layout": {
@@ -325,20 +356,200 @@
"lmtime": 0,
"modified": false
},
"REFACTORING_PLAN.md": {
"type": "-",
"size": 3576,
"lmtime": 0,
"modified": false
},
"robots.txt": {
"type": "-",
"size": 25,
"lmtime": 0,
"modified": false
},
".serena": {},
"temp": {},
"templates": {
"backend_sites": {},
"backpro": {
"domains": {
"list.php": {
"type": "-",
"size": 2975,
"lmtime": 0,
"modified": false
}
}
},
"crm": {
"client-edit.php": {
"type": "-",
"size": 1998,
"lmtime": 1771236164967,
"modified": false
},
"main-view.php": {
"type": "-",
"size": 2103,
"lmtime": 1771236164967,
"modified": false
}
},
"cron": {
"main-view.php": {
"type": "-",
"size": 2995,
"lmtime": 0,
"modified": false
}
},
"finances": {
"category-edit.php": {
"type": "-",
"size": 1965,
"lmtime": 0,
"modified": false
},
"main-view.php": {
"type": "-",
"size": 13340,
"lmtime": 1771236164969,
"modified": false
},
"operation-edit.php": {
"type": "-",
"size": 4351,
"lmtime": 1771236164970,
"modified": false
},
"operations-list.php": {
"type": "-",
"size": 4312,
"lmtime": 0,
"modified": false
}
},
"html": {
"button.php": {
"type": "-",
"size": 1093,
"lmtime": 0,
"modified": false
},
"form-text.php": {
"type": "-",
"size": 269,
"lmtime": 0,
"modified": false
},
"input-icon.php": {
"type": "-",
"size": 2239,
"lmtime": 0,
"modified": false
},
"input.php": {
"type": "-",
"size": 1480,
"lmtime": 0,
"modified": false
},
"input-switch.php": {
"type": "-",
"size": 1012,
"lmtime": 0,
"modified": false
},
"panel.php": {
"type": "-",
"size": 249,
"lmtime": 0,
"modified": false
},
"select.php": {
"type": "-",
"size": 1404,
"lmtime": 0,
"modified": false
},
"textarea.php": {
"type": "-",
"size": 1383,
"lmtime": 1770733546656,
"modified": false
}
},
"projects": {
"closed-tasks.php": {
"type": "-",
"size": 5365,
"lmtime": 0,
"modified": false
},
"inprogress-tasks.php": {
"type": "-",
"size": 6860,
"lmtime": 0,
"modified": false
},
"main_view.php": {
"type": "-",
"size": 2500,
"lmtime": 0,
"modified": false
},
"project_edit.php": {
"type": "-",
"size": 2429,
"lmtime": 0,
"modified": false
},
"task-details.php": {
"type": "-",
"size": 5602,
"lmtime": 0,
"modified": false
},
"task-edit.php": {
"type": "-",
"size": 7739,
"lmtime": 1770733570166,
"modified": false
},
"tasks.php": {
"type": "-",
"size": 27718,
"lmtime": 0,
"modified": false
},
"toreview-tasks.php": {
"type": "-",
"size": 6399,
"lmtime": 0,
"modified": false
},
"unassigned-tasks.php": {
"type": "-",
"size": 6002,
"lmtime": 0,
"modified": false
}
},
"site": {
"layout-cron.php": {
"type": "-",
"size": 6400,
"lmtime": 1770653884637,
"modified": true
},
"layout-logged.php": {
"type": "-",
"size": 8738,
"lmtime": 1770653877600,
"modified": true
},
"layout-unlogged.php": {
"type": "-",
"size": 986,
"lmtime": 0,
"modified": false
}
},
"tasks": {
"filtr_save_form.php": {
"type": "-",
@@ -392,9 +603,9 @@
},
"main-view.php": {
"type": "-",
"size": 2067,
"lmtime": 1770653623175,
"modified": true
"size": 3773,
"lmtime": 1772130816909,
"modified": false
},
"settings.php": {
"type": "-",
@@ -409,78 +620,22 @@
"modified": false
}
},
"site": {
"layout-cron.php": {
"type": "-",
"size": 6369,
"lmtime": 1770653884637,
"modified": false
},
"layout-logged.php": {
"type": "-",
"size": 6762,
"lmtime": 1770653877600,
"modified": false
},
"layout-unlogged.php": {
"type": "-",
"size": 986,
"lmtime": 0,
"modified": false
}
},
"html": {
"textarea.php": {
"type": "-",
"size": 1383,
"lmtime": 1770733546656,
"modified": false
}
},
"projects": {
"task-edit.php": {
"type": "-",
"size": 7739,
"lmtime": 1770733570166,
"modified": false
}
},
"crm": {
"client-edit.php": {
"type": "-",
"size": 1998,
"lmtime": 1771236164967,
"modified": false
},
"main-view.php": {
"type": "-",
"size": 2103,
"lmtime": 1771236164967,
"modified": false
}
},
"finances": {
"wiki": {
"category-edit.php": {
"type": "-",
"size": 1965,
"size": 3635,
"lmtime": 0,
"modified": false
},
"category-preview.php": {
"type": "-",
"size": 883,
"lmtime": 0,
"modified": false
},
"main-view.php": {
"type": "-",
"size": 13340,
"lmtime": 1771236164969,
"modified": false
},
"operation-edit.php": {
"type": "-",
"size": 4351,
"lmtime": 1771236164970,
"modified": false
},
"operations-list.php": {
"type": "-",
"size": 4312,
"size": 3649,
"lmtime": 0,
"modified": false
}
@@ -497,11 +652,17 @@
},
"Domain": {
"Users": {
"PermissionRepositoryTest.php": {
"type": "-",
"size": 1373,
"lmtime": 1772131187402,
"modified": false
},
"UserRepositoryTest.php": {
"type": "-",
"size": 1540,
"size": 1593,
"lmtime": 1770653587539,
"modified": false
"modified": true
}
},
"Tasks": {

View File

@@ -28,10 +28,22 @@ class Users
public static function logout()
{
global $mdb, $user;
$domain = preg_replace( '#^(http(s)?://)?w{3}\.#', '$1', $_SERVER['SERVER_NAME'] );
$cookie_name = str_replace( '.', '-', $domain );
setcookie( $cookie_name, "", strtotime( "-1 year" ), "/", $domain );
if ( $user && isset( $user['id'] ) )
$mdb -> update( 'users', [ 'remember_token' => null ], [ 'id' => $user['id'] ] );
setcookie( $cookie_name, "", [
'expires' => strtotime( "-1 year" ),
'path' => '/',
'domain' => $domain,
'secure' => true,
'httponly' => true,
'samesite' => 'Lax'
] );
session_destroy();
header( 'Location: /' );
exit;
@@ -111,16 +123,30 @@ class Users
$domain = preg_replace( '#^(http(s)?://)?w{3}\.#', '$1', $_SERVER['SERVER_NAME'] );
$cookie_name = str_replace( '.', '-', $domain );
if ( \S::get( 'remember' ) )
if ( \S::get( 'remember' ) === 'true' )
{
$token = bin2hex( random_bytes( 32 ) );
$mdb -> update( 'users', [ 'remember_token' => $token ], [ 'id' => $user['id'] ] );
setcookie( $cookie_name, $token, strtotime( "+1 year" ), "/", $domain, true, true );
setcookie( $cookie_name, $token, [
'expires' => strtotime( "+1 year" ),
'path' => '/',
'domain' => $domain,
'secure' => true,
'httponly' => true,
'samesite' => 'Lax'
] );
}
else
{
$mdb -> update( 'users', [ 'remember_token' => null ], [ 'id' => $user['id'] ] );
setcookie( $cookie_name, "", strtotime( "-1 year" ), "/", $domain );
setcookie( $cookie_name, "", [
'expires' => strtotime( "-1 year" ),
'path' => '/',
'domain' => $domain,
'secure' => true,
'httponly' => true,
'samesite' => 'Lax'
] );
}
\S::set_session( 'user', $user );

View File

@@ -90,12 +90,24 @@ if ( isset( $_COOKIE[$cookie_name] ) && !isset( $_SESSION['user'] ) )
{
$remember_token = $_COOKIE[$cookie_name];
if ( is_string( $remember_token ) && strlen( $remember_token ) === 64 )
if ( is_string( $remember_token ) && strlen( $remember_token ) === 64 && ctype_xdigit( $remember_token ) )
{
$user_tmp = $mdb -> get( 'users', '*', [ 'remember_token' => $remember_token ] );
if ( $user_tmp )
\S::set_session( 'user', $user_tmp );
}
else
{
// stare cookie w nieaktualnym formacie — usunięcie
setcookie( $cookie_name, "", [
'expires' => strtotime( "-1 year" ),
'path' => '/',
'domain' => $domain,
'secure' => true,
'httponly' => true,
'samesite' => 'Lax'
] );
}
}
$user = \S::get_session('user');

View File

@@ -73,7 +73,7 @@
{
email: email,
password: password,
remember: $( '#remeber' ).is( ':checked' )
remember: $( '#remeber' ).is( ':checked' ) ? 'true' : 'false'
},
beforeSend: function()
{