Skip to content
Permalink
Browse files

Implement password reset page through partials.

And make some other changes there.
  • Loading branch information
kohler committed Nov 19, 2019
1 parent 49fcb77 commit 2f0bdaf70e48984e523090bcf5857ed9c1481848
Showing with 216 additions and 119 deletions.
  1. +21 −0 etc/pagepartials.json
  2. +14 −14 lib/login.php
  3. +1 −93 resetpassword.php
  4. +3 −1 src/conference.php
  5. +10 −5 src/contact.php
  6. +8 −5 src/partials/p_home.php
  7. +156 −0 src/partials/p_resetpassword.php
  8. +1 −0 src/tarball.sh
  9. +2 −1 stylesheets/style.css
@@ -98,5 +98,26 @@
{
"name": "home/submissions", "position": 7000,
"render_callback": "*Home_Partial::render_submissions"
},

{
"name": "resetpassword/request", "position": 100,
"request_callback": "*ResetPassword_Partial::reset_request"
},
{
"name": "resetpassword/head", "position": 1000,
"render_callback": "*ResetPassword_Partial::render_reset_head"
},
{
"name": "resetpassword/message", "position": 2000,
"alias": "home/message"
},
{
"name": "resetpassword/welcome", "position": 2500,
"alias": "home/welcome"
},
{
"name": "resetpassword/body", "position": 3000,
"render_callback": "*ResetPassword_Partial::render_reset_body"
}
]
@@ -55,15 +55,18 @@ static function check_http_auth(Contact $user, Qrequest $qreq) {
&& validate_email($qreq->email . "@" . $x)) {
$qreq->preferredEmail = $qreq->email . "@" . $x;
}
self::login_redirect($conf, $qreq, "go"); // redirect on success
$url = self::login($conf, $qreq, "go");
if ($url !== false) {
Navigation::redirect($url);
}

$conf->header("Error", "home");
Conf::msg_error("This site is using HTTP authentication to manage its users, and you have provided incorrect authentication data.");
$conf->footer();
exit;
}

static function login_redirect(Conf $conf, Qrequest $qreq, $signinaction) {
static function login(Conf $conf, Qrequest $qreq, $signinaction) {
global $Now;
$external_login = $conf->external_login();

@@ -76,10 +79,8 @@ static function login_redirect(Conf $conf, Qrequest $qreq, $signinaction) {
}

// do LDAP login before validation, since we might create an account
if ($conf->opt("ldapLogin")) {
if (!self::ldap_login($qreq)) {
return null;
}
if ($conf->opt("ldapLogin") && !self::ldap_login($qreq)) {
return false;
}

// look up user in our database
@@ -106,8 +107,7 @@ static function login_redirect(Conf $conf, Qrequest $qreq, $signinaction) {
}
$user = self::create_account($conf, $qreq, $user, $cdb_user);
if (!$user) {
$conf->self_redirect(null, ["signin" => 1, "email" => $qreq->email]);
return null;
return $conf->selfurl(null, ["signin" => 1, "email" => $qreq->email]);
}
// If we get here, it's the first account and we're going to
// log them in automatically. XXX should show the password
@@ -118,7 +118,8 @@ static function login_redirect(Conf $conf, Qrequest $qreq, $signinaction) {
if (!$user && $external_login) {
$user = Contact::create($conf, null, $qreq->as_array(), Contact::SAVE_ANY_EMAIL);
if (!$user) {
return Conf::msg_error($conf->db_error_html(true, "while adding your account"));
Conf::msg_error($conf->db_error_html(true, "while adding your account"));
return false;
}
}

@@ -140,13 +141,12 @@ static function login_redirect(Conf $conf, Qrequest $qreq, $signinaction) {
if ($signinaction === "forgot" && $qreq->post_ok()) {
$worked = $xuser->sendAccountInfo("forgot", true);
if ($worked === "@resetpassword") {
$conf->msg("A password reset link has been emailed to " . htmlspecialchars($qreq->email) . ". When you receive that email, visit that link to create a new password.", "xconfirm");
$conf->msg("A password reset link has been emailed to you. When you receive that email, visit that link to create a new password.", "xconfirm");
} else if ($worked) {
$conf->msg("Your password has been emailed to " . htmlspecialchars($qreq->email) . ". When you receive that email, return here to sign in.", "xconfirm");
$conf->msg("Your password has been emailed to you. When you receive that email, return here to sign in.", "xconfirm");
$conf->log_for($xuser, null, "Password sent");
}
Navigation::redirect("");
return null;
return $conf->selfurl(null);
}

// check password
@@ -216,7 +216,7 @@ static function login_redirect(Conf $conf, Qrequest $qreq, $signinaction) {
if ($qreq->go !== null) {
$url .= "&go=" . urlencode($qreq->go);
}
Navigation::redirect($url);
return $url;
}

static function check_postlogin(Contact $user, Qrequest $qreq) {
@@ -2,96 +2,4 @@
// resetpassword.php -- HotCRP password reset page
// Copyright (c) 2006-2019 Eddie Kohler; see LICENSE.

require_once("src/initweb.php");

if ($Conf->external_login()) {
error_go(false, "Password reset links aren’t used for this conference. Contact your system administrator if you’ve forgotten your password.");
}

$resetcap = $Qreq->resetcap;
if ($resetcap === null
&& preg_match(',\A/(U?1[-\w]+)(?:/|\z),i', Navigation::path(), $m)) {
$resetcap = $m[1];
}
if (!$resetcap) {
error_go(false, "You didn’t enter the full password reset link into your browser. Make sure you include the reset code (the string of letters, numbers, and other characters at the end).");
}

$iscdb = substr($resetcap, 0, 1) === "U";
$capmgr = $Conf->capability_manager($resetcap);
$capdata = $capmgr->check($resetcap);
if (!$capdata || $capdata->capabilityType != CAPTYPE_RESETPASSWORD) {
error_go(false, "That password reset code has expired, or you didn’t enter it correctly.");
}

if ($iscdb) {
$Acct = $Conf->contactdb_user_by_id($capdata->contactId);
} else {
$Acct = $Conf->user_by_id($capdata->contactId);
}
if (!$Acct) {
error_go(false, "That password reset code refers to a user who no longer exists. Either create a new account or contact the conference administrator.");
}

// don't show information about the current user, if there is one
$Me = new Contact;

if (isset($Qreq->go) && $Qreq->post_ok()) {
$Qreq->password = trim((string) $Qreq->password);
$Qreq->password2 = trim((string) $Qreq->password2);
if ($Qreq->password === "") {
Conf::msg_error("You must enter a password.");
} else if (!Contact::valid_password($Qreq->password)) {
Conf::msg_error("Invalid password.");
} else if ($Qreq->password !== $Qreq->password2) {
Conf::msg_error("The two passwords you entered did not match.");
} else {
$Acct->change_password($Qreq->password, 0);
if (!$iscdb || !($log_acct = $Conf->user_by_email($Acct->email))) {
$log_acct = $Acct;
}
$log_acct->log_activity("Password reset via " . substr($resetcap, 0, 8) . "...");
$Conf->confirmMsg("Your password has been changed. You may now sign in to the conference site.");
$capmgr->delete($capdata);
$Me->save_session("password_reset", (object) array("time" => $Now, "email" => $Acct->email, "password" => $Qreq->password));
go(hoturl("index"));
}
Ht::error_at("password");
}

$Conf->header("Reset password", "resetpassword", ["action_bar" => false]);

if (!isset($Qreq->autopassword)
|| trim($Qreq->autopassword) !== $Qreq->autopassword
|| strlen($Qreq->autopassword) < 16
|| !preg_match("/\\A[-0-9A-Za-z@_+=]*\\z/", $Qreq->autopassword))
$Qreq->autopassword = Contact::random_password();

echo '<div class="homegrp">
Welcome to the ', htmlspecialchars($Conf->full_name()), " submissions site.";
if ($Conf->opt("conferenceSite"))
echo " For general information about ", htmlspecialchars($Conf->short_name), ", see <a href=\"", htmlspecialchars($Conf->opt("conferenceSite")), "\">the conference site</a>.";

echo "</div>
<div class=\"homegrp\" id=\"homereset\">\n",
Ht::form(hoturl_post("resetpassword")),
'<div class="f-contain">',
Ht::hidden("resetcap", $resetcap),
Ht::hidden("autopassword", $Qreq->autopassword),
"<p>Use this form to reset your password. You may want to use the random password we’ve chosen.</p>",
'<div class="f-i"><label>Email</label>', htmlspecialchars($Acct->email), '</div>',
'<div class="f-i"><label>Suggested password</label>',
htmlspecialchars($Qreq->autopassword), '</div>';
echo '<div class="', Ht::control_class("password", "f-i"), '">
<label for="password">New password</label>',
Ht::password("password", "", ["class" => "want-focus", "tabindex" => 1, "size" => 36, "id" => "password", "autocomplete" => "new-password"]), '</div>
<div class="', Ht::control_class("password", "f-i"), '">
<label for="password2">New password (again)</label>',
Ht::password("password2", "", ["tabindex" => 1, "size" => 36, "id" => "password2", "autocomplete" => "new-password"]), '</div>
<div class="f-i" style="margin-top:2em">',
Ht::submit("resetpassword", "Reset password", ["class" => "btn-primary"]),
"</div>
</div></form></div>\n";
Ht::stash_script("focus_within(\$(\"#homereset\"));window.scroll(0,0)");

$Conf->footer();
require_once("index.php");
@@ -4392,8 +4392,10 @@ function call_hooks($name, Contact $user = null /* ... args */) {
function page_template($page) {
if ($page === "index") {
return (object) ["name" => "index", "group" => "home"];
} else if (in_array($page, ["doc", "paper", "search", "review", "assign", "autoassign", "bulkassign", "buzzer", "checkupdates", "profile", "conflictassign", "deadlines", "graph", "help", "log", "mail", "manualassign", "mergeaccounts", "offline", "resetpassword", "reviewprefs", "scorechart", "settings", "users"])) {
} else if (in_array($page, ["doc", "paper", "search", "review", "assign", "autoassign", "bulkassign", "buzzer", "checkupdates", "profile", "conflictassign", "deadlines", "graph", "help", "log", "mail", "manualassign", "mergeaccounts", "offline", "reviewprefs", "scorechart", "settings", "users"])) {
return (object) ["name" => $page, "require" => "$page.php"];
} else if ($page === "resetpassword") {
return (object) ["name" => $page, "group" => $page];
} else {
return null;
}
@@ -1234,19 +1234,24 @@ function apply_updater($updater, $is_cdb) {

static function create(Conf $conf, $actor, $reg, $flags = 0, $roles = 0) {
// clean registration
if (is_array($reg))
if (is_array($reg)) {
$reg = (object) $reg;
}
assert(is_string($reg->email));
$reg->email = trim($reg->email);
assert($reg->email !== "");
if (!isset($reg->firstName) && isset($reg->first))
if (!isset($reg->firstName) && isset($reg->first)) {
$reg->firstName = $reg->first;
if (!isset($reg->lastName) && isset($reg->last))
}
if (!isset($reg->lastName) && isset($reg->last)) {
$reg->lastName = $reg->last;
if (isset($reg->name) && !isset($reg->firstName) && !isset($reg->lastName))
}
if (isset($reg->name) && !isset($reg->firstName) && !isset($reg->lastName)) {
list($reg->firstName, $reg->lastName) = Text::split_name($reg->name);
if (isset($reg->preferred_email) && !isset($reg->preferredEmail))
}
if (isset($reg->preferred_email) && !isset($reg->preferredEmail)) {
$reg->preferredEmail = $reg->preferred_email;
}

// look up existing accounts
$valid_email = validate_email($reg->email);
@@ -76,7 +76,10 @@ static function signin_requests(Contact $user, Qrequest $qreq) {
if ($user->conf->opt("httpAuthLogin")) {
LoginHelper::check_http_auth($user, $qreq);
} else if ($signin) {
LoginHelper::login_redirect($user->conf, $qreq, $signinaction);
$url = LoginHelper::login($user->conf, $qreq, $signinaction);
if ($url !== false) {
Navigation::redirect($url);
}
} else if (($signin || $signout) && $qreq->post) {
unset($qreq->signin, $qreq->signout);
$user->conf->self_redirect($qreq);
@@ -220,7 +223,7 @@ function render_welcome(Contact $user) {
echo '</div>';
}

private function _forgot_message(Conf $conf) {
static function forgot_message(Conf $conf) {
return $conf->_("Enter your email and we’ll send you instructions for signing in.");
}
private function _create_message(Conf $conf) {
@@ -265,7 +268,7 @@ private function render_signin_login(Contact $user, Qrequest $qreq) {
echo '<div class="', Ht::control_class("password", "f-i"), '">';
if (!$is_external_login) {
echo '<div class="float-right"><a href="?signin=1&amp;action=forgot" class="n x small ui js-forgot-password" data-message="',
htmlspecialchars($this->_forgot_message($conf)),
htmlspecialchars(self::forgot_message($conf)),
'">Forgot your password?</a></div>';
}
echo Ht::label("Password", "signin_password"),
@@ -294,7 +297,7 @@ private function render_signin_login(Contact $user, Qrequest $qreq) {

private function render_signin_forgot(Contact $user, Qrequest $qreq) {
echo $this->render_h2_home("Reset password");
if (($m = $this->_forgot_message($user->conf))) {
if (($m = self::forgot_message($user->conf))) {
echo '<p class="mb-5">', $m, '</p>';
}
$this->_render_signin_email($user->conf, $qreq->email, true);
@@ -321,7 +324,7 @@ function render_signin(Contact $user, Qrequest $qreq) {
echo '<div class="homegrp fold',
$qreq->signin ? "o" : "c",
'" id="homeacct">',
Ht::form($user->conf->hoturl("index", ["signin" => 1]), ["class" => "ui-submit js-signin"]),
Ht::form($user->conf->hoturl("index", ["signin" => 1]), ["class" => "ui-submit js-signin compact-form"]),
Ht::hidden("post", post_value(true));
$action = $qreq->signin ? $qreq->action : null;
if ($action === "forgot" && !$user->conf->external_login()) {

0 comments on commit 2f0bdaf

Please sign in to comment.
You can’t perform that action at this time.