From 75034601726c6f2ae32c92e896bc15ed7f6e567b Mon Sep 17 00:00:00 2001 From: Eddie Kohler Date: Wed, 20 Dec 2023 15:09:46 -0500 Subject: [PATCH] UpdateSession `usec`: Elements can include email, rather than uindex. Need email before a user index is set. --- lib/login.php | 14 ++------ src/contact.php | 4 +-- src/pages/p_oauth.php | 2 +- src/pages/p_signin.php | 9 ++--- src/updatesession.php | 71 +++++++++++++++++++++---------------- src/userinfo/u_security.php | 4 +-- 6 files changed, 53 insertions(+), 51 deletions(-) diff --git a/lib/login.php b/lib/login.php index 1fbd310681..0d79977a63 100644 --- a/lib/login.php +++ b/lib/login.php @@ -148,10 +148,8 @@ static function login_complete($info, Qrequest $qreq) { // store authentication $qreq->qsession()->open_new_sid(); - $uindex = UpdateSession::user_change($qreq, $xuser->email, true); - foreach ($info["usec"] ?? [] as $type) { - UpdateSession::usec_add_uindex($qreq, $uindex, $type, 0, true); - } + UpdateSession::user_change($qreq, $xuser->email, true); + UpdateSession::usec_add_list($qreq, $xuser->email, $info["usec"] ?? [], 0); // activate $user = $xuser->activate($qreq, false); @@ -175,14 +173,6 @@ static function login_complete($info, Qrequest $qreq) { return $info; } - /** @param Qrequest $qreq - * @param string $email - * @param int $instr - * @deprecated */ - static function change_session_user($qreq, $email, $instr) { - UpdateSession::user_change($qreq, $email, $instr > 0); - } - /** @return bool */ static private function check_setup_phase(Contact $user) { if ($user->conf->setting("setupPhase")) { diff --git a/src/contact.php b/src/contact.php index e7a0257d8d..46fad6b5ab 100644 --- a/src/contact.php +++ b/src/contact.php @@ -2365,7 +2365,7 @@ function check_password_info($input) { // deny if no match if (!$cdb_ok && !$local_ok) { $x = [ - "ok" => false, "invalid" => true, "usec" => [0], + "ok" => false, "invalid" => true, "usec" => [[0, false]], "can_reset" => $this->can_reset_password() ]; // report information about passwords @@ -2446,7 +2446,7 @@ function check_password_info($input) { } } - return ["ok" => true, "user" => $this, "usec" => [0]]; + return ["ok" => true, "user" => $this, "usec" => [[0, true]]]; } /** @param string $input diff --git a/src/pages/p_oauth.php b/src/pages/p_oauth.php index 9f40f72aa5..e643d0e5ad 100644 --- a/src/pages/p_oauth.php +++ b/src/pages/p_oauth.php @@ -237,7 +237,7 @@ private function instance_response($authi, $tok, $tokdata) { $user = $info["user"]; $this->conf->feedback_msg(new MessageItem(null, "<0>Signed in", MessageSet::SUCCESS)); $uindex = UpdateSession::user_change($this->qreq, $user->email, true); - UpdateSession::usec_add_uindex($this->qreq, $uindex, 1, 0, true); + UpdateSession::usec_add($this->qreq, $user->email, 1, 0, true); throw new Redirection(hoturl_add_raw($tokdata->site_uri, "i=" . urlencode($user->email))); } } diff --git a/src/pages/p_signin.php b/src/pages/p_signin.php index d4745dd844..e5fe983c78 100644 --- a/src/pages/p_signin.php +++ b/src/pages/p_signin.php @@ -83,17 +83,18 @@ function signin_request(Contact $user, Qrequest $qreq, $cs) { static function signin_request_basic(Contact $user, Qrequest $qreq, $cs, $info) { if (!$info["ok"]) { return $info; - } else { - return LoginHelper::login_info($user->conf, $qreq); } + return LoginHelper::login_info($user->conf, $qreq); } static function signin_request_success(Contact $user, Qrequest $qreq, $cs, $info) { if (!$info["ok"]) { + if (!empty($info["usec"])) { + UpdateSession::usec_add_list($qreq, $qreq->email, $info["usec"], 0); + } return $info; - } else { - return LoginHelper::login_complete($info, $qreq); } + return LoginHelper::login_complete($info, $qreq); } /** @param string $token diff --git a/src/updatesession.php b/src/updatesession.php index a8b5bfd881..f5089b8825 100644 --- a/src/updatesession.php +++ b/src/updatesession.php @@ -119,63 +119,63 @@ static function user_change($qreq, $email, $add) { return $add ? $ui : -1; } - /** @param 0|1|2 $type - * @param 0|1 $reason - * @param int $bound - * @return ?bool */ - static function usec_query(Qrequest $qreq, $type, $reason, $bound = 0) { - if (($uindex = $qreq->user()->session_index()) >= 0) { - return self::usec_query_uindex($qreq, $uindex, $type, $reason, $bound); - } else { - return null; - } - } - - /** @param int $uindex + /** @param string $email * @param 0|1|2 $type * @param 0|1 $reason * @param int $bound - * @return ?bool */ - static function usec_query_uindex(Qrequest $qreq, $uindex, $type, $reason, $bound = 0) { + * @return bool */ + static function usec_query(Qrequest $qreq, $email, $type, $reason, $bound = 0) { + $uindex = Contact::session_index_by_email($qreq, $email); $usec = $qreq->gsession("usec") ?? []; - $success = $bound > 0 ? null : false; + $success = false; foreach ($qreq->gsession("usec") ?? [] as $e) { - if (($e["u"] ?? 0) === $uindex + if ((isset($e["e"]) + ? strcasecmp($e["e"], $email) === 0 + : ($e["u"] ?? 0) === $uindex) && ($e["t"] ?? 0) === $type && ($e["r"] ?? 0) === $reason && $e["a"] >= $bound) { $success = !($e["x"] ?? false); - } else if ($success === null - && $e["a"] >= $bound) { - $success = false; } } return $success; } - /** @param 0|1|2 $type + /** @param int $uindex + * @param 0|1|2 $type * @param 0|1 $reason - * @param bool $success */ - static function usec_add(Qrequest $qreq, $type, $reason, $success) { - if (($uindex = $qreq->user()->session_index()) >= 0) { - self::usec_add_uindex($qreq, $uindex, $type, $reason, $success); - } + * @param int $bound + * @return ?bool + * @deprecated */ + static function usec_query_uindex(Qrequest $qreq, $uindex, $type, $reason, $bound = 0) { + return false; } - /** @param int $uindex + /** @param string $email * @param 0|1|2 $type * @param 0|1 $reason * @param bool $success */ - static function usec_add_uindex(Qrequest $qreq, $uindex, $type, $reason, $success) { + static function usec_add(Qrequest $qreq, $email, $type, $reason, $success) { + $uindex = Contact::session_index_by_email($qreq, $email); $old_usec = $qreq->gsession("usec") ?? []; $nold_usec = count($old_usec); $usec = []; foreach ($old_usec as $i => $e) { + if ($uindex >= 0 + && isset($e["e"]) + && strcasecmp($e["e"], $email) === 0) { + unset($e["e"]); + if ($uindex > 0) { + $e["u"] = $uindex; + } + } if ((($e["r"] ?? 0) === 1 && $e["a"] < Conf::$now - 86400) || ($success - && ($e["u"] ?? 0) === $uindex + && (isset($e["e"]) + ? strcasecmp($e["e"], $email) === 0 + : ($e["u"] ?? 0) === $uindex) && ($e["t"] ?? 0) === $type && ($e["r"] ?? 0) === $reason) || ($nold_usec > 150 @@ -187,7 +187,9 @@ static function usec_add_uindex(Qrequest $qreq, $uindex, $type, $reason, $succes } $x = []; - if ($uindex !== 0) { + if ($uindex < 0) { + $x["e"] = $email; + } else if ($uindex > 0) { $x["u"] = $uindex; } if ($type !== 0) { @@ -203,4 +205,13 @@ static function usec_add_uindex(Qrequest $qreq, $uindex, $type, $reason, $succes $usec[] = $x; $qreq->set_gsession("usec", $usec); } + + /** @param string $email + * @param list $useclist + * @param 0|1 $reason */ + static function usec_add_list(Qrequest $qreq, $email, $useclist, $reason) { + foreach ($useclist as $elt) { + self::usec_add($qreq, $email, $elt[0], $reason, $elt[1]); + } + } } diff --git a/src/userinfo/u_security.php b/src/userinfo/u_security.php index d8f22ff222..1526ba1e4c 100644 --- a/src/userinfo/u_security.php +++ b/src/userinfo/u_security.php @@ -18,7 +18,7 @@ class Security_UserInfo { function __construct(UserStatus $us) { $this->us = $us; $this->_approved = $us->allow_security() - && UpdateSession::usec_query($us->qreq, 0, 1, Conf::$now - 300); + && UpdateSession::usec_query($us->qreq, $us->viewer->email, 0, 1, Conf::$now - 300); } function parse_qreq(UserStatus $us) { @@ -32,8 +32,8 @@ function parse_qreq(UserStatus $us) { } } else { $info = $us->viewer->check_password_info($pw); + UpdateSession::usec_add_list($us->qreq, $us->viewer->email, $info["usec"] ?? [], 1); $this->_approved = $info["ok"]; - UpdateSession::usec_add($us->qreq, 0, 1, $this->_approved); if (!$this->_approved) { $this->_approval_errors[] = MessageItem::error_at("oldpassword", "<0>Incorrect current password"); }