From f692565a30789c76b8df4efbdda948de6abb71f9 Mon Sep 17 00:00:00 2001 From: Dan Langille Date: Sun, 23 Jun 2024 11:57:36 +0000 Subject: [PATCH 1/3] Allow multiple logins The current code does not allow multiple logins from different browsers / clients. This changes that. A database modification is required. re #574 --- classes/user.php | 7 +++++-- include/getvalues.php | 2 +- www/bouncing.php | 2 +- www/customize.php | 12 ++++-------- www/delete-account.php | 1 - www/login.php | 9 ++++++--- www/logout.php | 2 +- www/new-user.php | 6 +++--- 8 files changed, 21 insertions(+), 20 deletions(-) diff --git a/classes/user.php b/classes/user.php index 0a324d66..544337cb 100644 --- a/classes/user.php +++ b/classes/user.php @@ -72,9 +72,12 @@ function Fetch($ID) { function FetchByCookie($Cookie) { + # might want to make this a stored procedure $sql = "-- " . __FILE__ . '::' . __FUNCTION__ . "\n" . 'SELECT users.* - FROM users - WHERE cookie = $1'; + FROM users join user_cookie on users.id = user_cookie.user_id + WHERE user_cookie.cookie = $1'; + + $sql = "-- " . __FILE__ . '::' . __FUNCTION__ . "\n" . 'select * from user_fetch_by_cookie($1)'; $this->LocalResult = pg_query_params($this->dbh, $sql, array($Cookie)); if ($this->LocalResult) { diff --git a/include/getvalues.php b/include/getvalues.php index cbc75cda..b8e51a9a 100644 --- a/include/getvalues.php +++ b/include/getvalues.php @@ -58,7 +58,7 @@ $User->name = ''; $User->id = 0; -// This is used to determine whether or not the cach can be used. +// This is used to determine whether or not the cache can be used. $DefaultMaxArticles = $MaxArticles; if (IsSet($_COOKIE[USER_COOKIE_NAME])) { diff --git a/www/bouncing.php b/www/bouncing.php index 327d7afd..f9c703d8 100644 --- a/www/bouncing.php +++ b/www/bouncing.php @@ -21,7 +21,7 @@ $visitor = $_COOKIE[USER_COOKIE_NAME]; if ($submit) { - $sql = "update users set emailbouncecount = 0 where cookie = $1"; + $sql = "select * from user_clear_bouncecount($1)"; if ($Debug) { echo $sql; } diff --git a/www/customize.php b/www/customize.php index 33139713..9191b670 100644 --- a/www/customize.php +++ b/www/customize.php @@ -97,11 +97,7 @@ if ($OK) { // get the existing email in case we need to reset the bounce count - $sql = "select email from users where cookie = '$visitor'"; - $result = pg_query($db, $sql); - if ($result) { - $myrow = pg_fetch_array ($result, 0); - + if (IsSet($User)) { $sql = " UPDATE users SET email = '$email', @@ -110,7 +106,7 @@ set_focus_search = $set_focus_search"; // if they are changing the email, reset the bouncecount. - if ($myrow["email"] != $email) { + if ($User->email != $email) { $sql .= ", emailbouncecount = 0 "; } @@ -119,13 +115,13 @@ $sql .= ", gen_salt('" . PW_HASH_METHOD . "', " . PW_HASH_COST ."))"; } - $sql .= " where cookie = '$visitor'"; + $sql .= " where users.id = (select user_id from user_cookie where cookie = $1)"; if ($Debug) { echo '
' . htmlentities($sql) . '
'; } - $result = pg_query($db, $sql); + $result = pg_query_params($db, $sql, array($visitor)); if ($result) { $AccountModified = 1; } diff --git a/www/delete-account.php b/www/delete-account.php index 80ed4dc5..69587a35 100644 --- a/www/delete-account.php +++ b/www/delete-account.php @@ -44,7 +44,6 @@ $result = pg_exec($db, "BEGIN"); // Delete from the user table. The database will take care of the rest -# $sql = "DELETE FROM users WHERE cookie = '$visitor'"; $sql = "SELECT DeleteUser($1)"; $result = pg_query_params($db, $sql, array($User->id)); if ($result) { diff --git a/www/login.php b/www/login.php index 0fc138cc..a7dd456a 100644 --- a/www/login.php +++ b/www/login.php @@ -86,12 +86,15 @@ $Cookie = $user->createUserToken(); # we should use $user to save this... - $sql = "UPDATE users SET cookie = $1 WHERE id = $2"; + $expires = time() + 60 * 60 * 24 * 120; # 120 days + $dt = new DateTime("@$expires"); // convert UNIX timestamp to PHP DateTime + $expires_dt = $dt->format('Y-m-d H:i:s'); // output = 2012-08-15 00:00:00 + $sql = 'SELECT * FROM user_set_cookie($1, $2, $3)'; # if we were doing this in a user object, we could retry when there was a cookie collision and we get a unique index error - $result = pg_query_params($db, $sql, array($Cookie, $row['id'])) or die('query failed ' . pg_last_error($db)); + $result = pg_query_params($db, $sql, array($row['id'], $Cookie, $expires_dt)) or die('query failed ' . pg_last_error($db)); SetCookie(USER_COOKIE_NAME, $Cookie, array( - 'expires' => time() + 60*60*24*120, + 'expires' => $expires, 'path' => '/', 'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'), 'httponly' => TRUE, diff --git a/www/logout.php b/www/logout.php index 73fb8444..6979874a 100644 --- a/www/logout.php +++ b/www/logout.php @@ -17,7 +17,7 @@ if (IsSet($_COOKIE[USER_COOKIE_NAME])) { $visitor = $_COOKIE[USER_COOKIE_NAME]; - $sql = "UPDATE users SET cookie = 'nocookie' WHERE cookie = $1"; + $sql = "select * from user_logout($1)"; #echo $sql; $result = pg_query_params($db, $sql, array($_COOKIE[USER_COOKIE_NAME])); } diff --git a/www/new-user.php b/www/new-user.php index 9bab52d4..fcc7854d 100644 --- a/www/new-user.php +++ b/www/new-user.php @@ -129,15 +129,15 @@ $UserID = freshports_GetNextValue($Sequence_User_ID, $db); if (IsSet($UserID)) { $sql = "insert into " . - "users (id, name, cookie, email, watch_notice_id, emailsitenotices_yn, type, ip_address, number_of_days, password_hash) " . - "values ($1, $2, $3, $4, $5::integer, $6, $7, $8, $9::integer, crypt($10, gen_salt($11, $12::integer)))"; + "users (id, name, email, watch_notice_id, emailsitenotices_yn, type, ip_address, number_of_days, password_hash) " . + "values ($1, $2, $3, $4::integer, $5, $6, $7, $8::integer, crypt($9, gen_salt($10, $11::integer)))"; syslog(LOG_ERR, "FreshPorts new user: '$UserID', '$UserLogin', '$email', " . $_SERVER["REMOTE_ADDR"]); $errors .= "
sql=" . $sql; $result = pg_query_params($db, $sql, array( - $UserID, $UserLogin, 'nocookie', $email, 1, 'N', 'U', $_SERVER["REMOTE_ADDR"], + $UserID, $UserLogin, $email, 1, 'N', 'U', $_SERVER["REMOTE_ADDR"], $numberofdays, $Password1, PW_HASH_METHOD, PW_HASH_COST )); From 0a57eadf84b7d2d50a6b61aa45ff472f8d2caf7b Mon Sep 17 00:00:00 2001 From: Dan Langille Date: Sun, 23 Jun 2024 12:34:00 +0000 Subject: [PATCH 2/3] Do not refer to users.cookie, now moved to user_cookie.cookie re: #574 --- classes/user.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/classes/user.php b/classes/user.php index 544337cb..9fe5f3c2 100644 --- a/classes/user.php +++ b/classes/user.php @@ -18,7 +18,6 @@ class User { var $id; var $name; var $password; - var $cookie; var $firstlogin; var $lastlogin; var $email; @@ -111,7 +110,6 @@ function PopulateValues($myrow) { $this->id = $myrow['id']; $this->name = $myrow['name']; $this->password = isset($myrow['password']) ? $myrow['password'] : null; - $this->cookie = $myrow['cookie']; $this->firstlogin = $myrow['firstlogin']; $this->lastlogin = $myrow['lastlogin']; $this->email = $myrow['email']; From 9ffd79e91884dbf33e8de7b9f3a2ee5d31315329 Mon Sep 17 00:00:00 2001 From: Dan Langille Date: Sun, 23 Jun 2024 13:43:13 +0000 Subject: [PATCH 3/3] When the cookie is used, extend the lifetime. If you login, and keep using the session, your cookie will be extended as you go. While here, do some colum aligments in include/getvalues.php --- include/constants.php | 3 ++- include/freshports.php | 21 +++++++++++++++++ include/getvalues.php | 52 ++++++++++++++++++++++-------------------- www/login.php | 12 ++-------- 4 files changed, 52 insertions(+), 36 deletions(-) diff --git a/include/constants.php b/include/constants.php index 6fc3d968..f42c71d5 100644 --- a/include/constants.php +++ b/include/constants.php @@ -38,7 +38,8 @@ $UserStatusUnconfirmed = "U"; -if (!defined('USER_COOKIE_NAME')) define('USER_COOKIE_NAME', "visitor"); +if (!defined('USER_COOKIE_NAME' )) define('USER_COOKIE_NAME', "visitor"); +if (!defined('USER_COOKIE_EXPIRES')) define('USER_COOKIE_EXPIRES', 60 * 60 * 24 * 120); # 120 days # # SEQUENCES diff --git a/include/freshports.php b/include/freshports.php index 3cdd0cd3..2a6ac09e 100644 --- a/include/freshports.php +++ b/include/freshports.php @@ -2763,3 +2763,24 @@ function FirstDateOfCurrentQuarter() { return date("Y-m-d", strtotime(date("Y") . '-' . $yearQuarter . '-01')); } + +function freshports_UserSetCookie($Cookie, $Expires = null) { + # set the cookie to the supplied expiry date + # initially set during login + # then reset/extended each time the cookie is used. + + if (Is_Null($Expires)) { + $Expires = time() + USER_COOKIE_EXPIRES; + } + + SetCookie(USER_COOKIE_NAME, $Cookie, array( + 'expires' => $Expires, + 'path' => '/', + 'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'), + 'httponly' => TRUE, + // it's probably common for users to navigate from other sites like portscout + // we want them to still be logged in if that's the case + 'samesite' => 'Lax', + )); + +} \ No newline at end of file diff --git a/include/getvalues.php b/include/getvalues.php index b8e51a9a..668ee3c7 100644 --- a/include/getvalues.php +++ b/include/getvalues.php @@ -13,10 +13,10 @@ $Debug = 0; -$FormatDateDefault = "%W, %b %e"; -$FormatTimeDefault = "%H:%i"; -$DaysMarkedAsNewDefault = 10; -$DefaultPageSize = 50; +$FormatDateDefault = "%W, %b %e"; +$FormatTimeDefault = "%H:%i"; +$DaysMarkedAsNewDefault = 10; +$DefaultPageSize = 50; // there are only a few places we want to show the last change. @@ -27,42 +27,44 @@ $MaxArticles = 40; $DaysNew = 10; -$MaxNumberOfPorts = 10; # max number of commits to show on index.php +$MaxNumberOfPorts = 10; # max number of commits to show on index.php $MaxNumberOfPortsLong = 100; # max number of commits to show on commits.php $ShowShortDescription = "Y"; -$ShowMaintainedBy = "Y"; -$ShowLastChange = "Y"; -$ShowDescriptionLink = "Y"; -$ShowChangesLink = "Y"; -$ShowDownloadPortLink = "Y"; -$ShowPackageLink = "Y"; -$ShowHomepageLink = "Y"; -$FormatDate = $FormatDateDefault; -$FormatTime = $FormatTimeDefault; -$DaysMarkedAsNew = $DaysMarkedAsNewDefault; -$EmailBounceCount = 0; -$CVSTimeAdjustment = -10800; # this is number of seconds the web server is relative to the cvs server. +$ShowMaintainedBy = "Y"; +$ShowLastChange = "Y"; +$ShowDescriptionLink = "Y"; +$ShowChangesLink = "Y"; +$ShowDownloadPortLink = "Y"; +$ShowPackageLink = "Y"; +$ShowHomepageLink = "Y"; +$FormatDate = $FormatDateDefault; +$FormatTime = $FormatTimeDefault; +$DaysMarkedAsNew = $DaysMarkedAsNewDefault; +$EmailBounceCount = 0; +$CVSTimeAdjustment = -10800; # this is number of seconds the web server is relative to the cvs server. # a value of -10800 means the web server is three hours east of the cvs server. # we can override that for a particular user. -$LocalTimeAdjustment = 0; # This can be used to display the time the webpage was loaded. -$NumberOfDays = 9; -$WatchListAsk = 1; +$LocalTimeAdjustment = 0; # This can be used to display the time the webpage was loaded. +$NumberOfDays = 9; +$WatchListAsk = 1; # # flags for showing various port parts. # -$ShowEverything = 0; -$ShowPortCreationDate = 0; +$ShowEverything = 0; +$ShowPortCreationDate = 0; -$User->name = ''; -$User->id = 0; +$User->name = ''; +$User->id = 0; -// This is used to determine whether or not the cache can be used. +// This is used to determine if the cache can be used. $DefaultMaxArticles = $MaxArticles; if (IsSet($_COOKIE[USER_COOKIE_NAME])) { $visitor = $_COOKIE[USER_COOKIE_NAME]; + # see a cookie? extend the cookie lifetime + freshports_UserSetCookie($visitor); } if (!empty($visitor)) { diff --git a/www/login.php b/www/login.php index a7dd456a..e5bbbc67 100644 --- a/www/login.php +++ b/www/login.php @@ -86,22 +86,14 @@ $Cookie = $user->createUserToken(); # we should use $user to save this... - $expires = time() + 60 * 60 * 24 * 120; # 120 days + $expires = time() + USER_COOKIE_EXPIRES; $dt = new DateTime("@$expires"); // convert UNIX timestamp to PHP DateTime $expires_dt = $dt->format('Y-m-d H:i:s'); // output = 2012-08-15 00:00:00 $sql = 'SELECT * FROM user_set_cookie($1, $2, $3)'; # if we were doing this in a user object, we could retry when there was a cookie collision and we get a unique index error $result = pg_query_params($db, $sql, array($row['id'], $Cookie, $expires_dt)) or die('query failed ' . pg_last_error($db)); - SetCookie(USER_COOKIE_NAME, $Cookie, array( - 'expires' => $expires, - 'path' => '/', - 'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'), - 'httponly' => TRUE, - // it's probably common for users to navigate from other sites like portscout - // we want them to still be logged in if that's the case - 'samesite' => 'Lax', - )); + freshports_UserSetCookie($Cookie, $expires); header("Location: /"); // Make sure that code below does not get executed when we redirect.