1<?php
2// mergeaccounts.php -- HotCRP account merging page
3// Copyright (c) 2006-2018 Eddie Kohler; see LICENSE.
4
5require_once("src/initweb.php");
6if (!$Me->email)
7    $Me->escape();
8$MergeError = "";
9
10function crpmerge($qreq, $MiniMe) {
11    global $Conf, $Me, $MergeError;
12
13    if (!$MiniMe->contactId && !$Me->contactId)
14        return ($MergeError = "Neither of those accounts has any data associated with this conference.");
15    // XXX `act as` merging might be useful?
16    if (strcasecmp($Me->email, $_SESSION["trueuser"]->email) != 0)
17        return ($MergeError = "You can’t merge accounts when acting as a different user.");
18    if ($MiniMe->data("locked") || $Me->data("locked"))
19        return ($MergeError = "Attempt to merge a locked account.");
20
21    // determine old & new users
22    if ($qreq->prefer)
23        $merger = new MergeContacts($Me, $MiniMe);
24    else
25        $merger = new MergeContacts($MiniMe, $Me);
26
27    // send mail at start of process
28    HotCRPMailer::send_to($merger->oldu, "@mergeaccount", null,
29                          array("cc" => Text::user_email_to($merger->newu),
30                                "other_contact" => $merger->newu));
31
32    // actually merge users or change email
33    $merger->run();
34
35    // update trueuser
36    if (strcasecmp($_SESSION["trueuser"]->email, $merger->newu->email) != 0)
37        $_SESSION["trueuser"] = (object) ["email" => $merger->newu->email];
38
39    if (!$merger->has_error()) {
40        $Conf->confirmMsg("Merged account " . htmlspecialchars($merger->oldu->email) . ".");
41        $merger->newu->log_activity("Merged account " . $merger->oldu->email);
42        go(hoturl("index"));
43    } else {
44        $merger->newu->log_activity("Merged account " . $merger->oldu->email . " with errors");
45        $MergeError = '<div class="multimessage">'
46            . join("\n", array_map(function ($m) { return '<div class="mmm">' . $m . '</div>'; },
47                                   $merger->errors()))
48            . '</div>';
49    }
50}
51
52if (isset($Qreq->merge) && $Qreq->post_ok()) {
53    if (!$Qreq->email) {
54        $MergeError = "Enter an email address to merge.";
55        Ht::set_control_class("email", "has-error");
56    } else if (!$Qreq->password) {
57        $MergeError = "Enter the password of the account to merge.";
58        Ht::set_control_class("password", "has-error");
59    } else {
60        $MiniMe = $Conf->user_by_email($Qreq->email);
61        if (!$MiniMe) {
62            $MergeError = "No account for " . htmlspecialchars($Qreq->email) . " exists.  Did you enter the correct email address?";
63            Ht::set_control_class("email", "has-error");
64        } else if (!$MiniMe->check_password($Qreq->password)) {
65            $MergeError = "That password is incorrect.";
66            Ht::set_control_class("password", "has-error");
67        } else if ($MiniMe->contactId == $Me->contactId) {
68            $Conf->confirmMsg("Accounts successfully merged.");
69            go(hoturl("index"));
70        } else
71            crpmerge($Qreq, $MiniMe);
72    }
73}
74
75$Conf->header("Merge accounts", "mergeaccounts");
76
77
78if ($MergeError)
79    Conf::msg_error($MergeError);
80else
81    $Conf->infoMsg(
82"You may have multiple accounts registered with the "
83. $Conf->short_name . " conference; perhaps "
84. "multiple people asked you to review a paper using "
85. "different email addresses. "
86. "If you have been informed of multiple accounts, "
87. "enter the email address and the password "
88. "of the secondary account. This will merge all the information from "
89. "that account into this one. "
90);
91
92echo Ht::form(hoturl_post("mergeaccounts"));
93
94// Try to prevent glasses interactions from screwing up merges
95echo Ht::hidden("actas", $Me->contactId);
96
97echo '<div class="', Ht::control_class("email", "f-i"), '">',
98    Ht::label("Other email", "merge_email"),
99    Ht::entry("email", (string) $Qreq->email,
100              ["size" => 36, "id" => "merge_email", "autocomplete" => "username", "tabindex" => 1]),
101    '</div>
102<div class="', Ht::control_class("password", "f-i fx"), '">',
103    Ht::label("Other password", "merge_password"),
104    Ht::password("password", "",
105                 ["size" => 36, "id" => "merge_password", "autocomplete" => "current-password", "tabindex" => 1]),
106    '</div>
107<div class="f-i">',
108    '<div class="checki"><label><span class="checkc">',
109    Ht::radio("prefer", 0, true), '</span>',
110    "Keep my current account (", htmlspecialchars($Me->email), ")</label></div>",
111    '<div class="checki"><label><span class="checkc">',
112    Ht::radio("prefer", 1), '</span>',
113    "Keep the account named above and delete my current account</label></div>",
114    '</div>',
115    Ht::actions([Ht::submit("merge", "Merge accounts", ["class" => "btn btn-primary"])]),
116    '</form>';
117
118
119$Conf->footer();
120