BioTorrents.de’s version of Gazelle
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

email_history2.php 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. <?php
  2. #declare(strict_types=1);
  3. /************************************************************************
  4. ||------------|| User email history page ||---------------------------||
  5. This page lists previous email addresses a user has used on the site. It
  6. gets called if $_GET['action'] == 'email'.
  7. It also requires $_GET['userid'] in order to get the data for the correct
  8. user.
  9. ************************************************************************/
  10. $UserID = $_GET['userid'];
  11. if (!is_number($UserID)) {
  12. error(404);
  13. }
  14. $DB->query("
  15. SELECT
  16. ui.JoinDate,
  17. p.Level AS Class
  18. FROM users_main AS um
  19. JOIN users_info AS ui ON um.ID = ui.UserID
  20. JOIN permissions AS p ON p.ID = um.PermissionID
  21. WHERE um.ID = $UserID");
  22. list($Joined, $Class) = $DB->next_record();
  23. if (!check_perms('users_view_email', $Class)) {
  24. error(403);
  25. }
  26. // todo: Is this even used?
  27. $UsersOnly = $_GET['usersonly'] ?? false;
  28. $DB->query("
  29. SELECT Username
  30. FROM users_main
  31. WHERE ID = $UserID");
  32. list($Username) = $DB->next_record();
  33. View::show_header("Email history for $Username");
  34. // Get current email (and matches)
  35. $DB->query(
  36. "
  37. SELECT
  38. m.Email,
  39. NOW() AS Time,
  40. m.IP,
  41. GROUP_CONCAT(h.UserID SEPARATOR '|') AS UserIDs,
  42. GROUP_CONCAT(h.Time SEPARATOR '|') AS UserSetTimes,
  43. GROUP_CONCAT(h.IP SEPARATOR '|') AS UserIPs,
  44. GROUP_CONCAT(m2.Username SEPARATOR '|') AS Usernames,
  45. GROUP_CONCAT(m2.Enabled SEPARATOR '|') AS UsersEnabled,
  46. GROUP_CONCAT(i.Donor SEPARATOR '|') AS UsersDonor,
  47. GROUP_CONCAT(i.Warned SEPARATOR '|') AS UsersWarned
  48. FROM users_main AS m
  49. LEFT JOIN users_history_emails AS h ON h.Email = m.Email
  50. AND h.UserID != m.ID
  51. LEFT JOIN users_main AS m2 ON m2.ID = h.UserID
  52. LEFT JOIN users_info AS i ON i.UserID = h.UserID
  53. WHERE m.ID = '$UserID'"
  54. );
  55. //$CurrentEmail = array_shift($DB->to_array());
  56. $CurrentEmail = ($DB->to_array())[0]; // Only variables should be passed by reference
  57. // Get historic emails (and matches)
  58. $DB->query(
  59. "
  60. SELECT
  61. h2.Email,
  62. h2.Time,
  63. h2.IP,
  64. h3.UserID AS UserIDs,
  65. h3.Time AS UserSetTimes,
  66. h3.IP AS UserIPs,
  67. m3.Username AS Usernames,
  68. m3.Enabled AS UsersEnabled,
  69. i2.Donor AS UsersDonor,
  70. i2.Warned AS UsersWarned
  71. FROM users_history_emails AS h2
  72. LEFT JOIN users_history_emails AS h3 ON h3.Email = h2.Email
  73. AND h3.UserID != h2.UserID
  74. LEFT JOIN users_main AS m3 ON m3.ID = h3.UserID
  75. LEFT JOIN users_info AS i2 ON i2.UserID = h3.UserID
  76. WHERE h2.UserID = '$UserID'
  77. ORDER BY Time DESC"
  78. );
  79. $History = $DB->to_array();
  80. // Current email
  81. $Current['Email'] = $CurrentEmail['Email'];
  82. $Current['StartTime'] = $History[0]['Time'];
  83. $Current['CurrentIP'] = $CurrentEmail['IP'];
  84. $Current['IP'] = $History[(count($History) - 1)]['IP'];
  85. // Matches for current email
  86. if ($CurrentEmail['Usernames'] != '') {
  87. $UserIDs = explode('|', $CurrentEmail['UserIDs']);
  88. $Usernames = explode('|', $CurrentEmail['Usernames']);
  89. $UsersEnabled = explode('|', $CurrentEmail['UsersEnabled']);
  90. $UsersDonor = explode('|', $CurrentEmail['UsersDonor']);
  91. $UsersWarned = explode('|', $CurrentEmail['UsersWarned']);
  92. $UserSetTimes = explode('|', $CurrentEmail['UserSetTimes']);
  93. $UserIPs = explode('|', $CurrentEmail['UserIPs']);
  94. foreach ($UserIDs as $Key => $Val) {
  95. $CurrentMatches[$Key]['Username'] = '&nbsp;&nbsp;&#187;&nbsp;'.Users::format_username($Val, true, true, true);
  96. $CurrentMatches[$Key]['IP'] = $UserIPs[$Key];
  97. $CurrentMatches[$Key]['EndTime'] = $UserSetTimes[$Key];
  98. }
  99. }
  100. // Email history records
  101. if (count($History) === 1) {
  102. $Invite['Email'] = $History[0]['Email'];
  103. $Invite['EndTime'] = $Joined;
  104. $Invite['AccountAge'] = date(time() + time() - strtotime($Joined)); // Same as EndTime but without ' ago'
  105. $Invite['IP'] = $History[0]['IP'];
  106. if (!$Current['StartTime']) {
  107. $Current['StartTime'] = $Joined;
  108. }
  109. } else {
  110. foreach ($History as $Key => $Val) {
  111. if (isset($History[$Key + 1]) && !$History[$Key + 1]['Time'] && !$Val['Time']) {
  112. // Invited email
  113. $Invite['Email'] = $Val['Email'];
  114. $Invite['EndTime'] = $Joined;
  115. $Invite['AccountAge'] = date(time() + time() - strtotime($Joined)); // Same as EndTime but without ' ago'
  116. $Invite['IP'] = $Val['IP'];
  117. } elseif (isset($History[$Key - 1]) && $History[$Key - 1]['Email'] != $Val['Email'] && $Val['Time']) {
  118. // Old email
  119. $i = 1;
  120. while ($Val['Email'] == $History[$Key + $i]['Email']) {
  121. $i++;
  122. }
  123. $Old[$Key]['StartTime'] = (isset($History[$Key + $i]) && $History[$Key + $i]['Time']) ? $History[$Key + $i]['Time'] : $Joined;
  124. $Old[$Key]['EndTime'] = $Val['Time'];
  125. $Old[$Key]['IP'] = $Val['IP'];
  126. $Old[$Key]['ElapsedTime'] = date(time() + strtotime($Old[$Key]['EndTime']) - strtotime($Old[$Key]['StartTime']));
  127. $Old[$Key]['Email'] = $Val['Email'];
  128. }
  129. if ($Val['Usernames'] != '') {
  130. // Match with old email
  131. $OldMatches[$Key]['Email'] = $Val['Email'];
  132. $OldMatches[$Key]['Username'] = '&nbsp;&nbsp;&#187;&nbsp;'.Users::format_username($Val['UserIDs'], true, true, true);
  133. $OldMatches[$Key]['EndTime'] = $Val['UserSetTimes'];
  134. $OldMatches[$Key]['IP'] = $Val['UserIPs'];
  135. }
  136. }
  137. }
  138. // Clean up arrays
  139. if ($Old ?? false) {
  140. $Old = array_reverse(array_reverse($Old));
  141. $LastOld = count($Old) - 1;
  142. if ($Old[$LastOld]['StartTime'] != $Invite['EndTime']) {
  143. // Make sure the timeline is intact (invite email was used as email for the account in the beginning)
  144. $Old[$LastOld + 1]['Email'] = $Invite['Email'];
  145. $Old[$LastOld + 1]['StartTime'] = $Invite['EndTime'];
  146. $Old[$LastOld + 1]['EndTime'] = $Old[$LastOld]['StartTime'];
  147. $Old[$LastOld + 1]['ElapsedTime'] = date(time() + strtotime($Old[$LastOld + 1]['EndTime']) - strtotime($Old[$LastOld + 1]['StartTime']));
  148. $Old[$LastOld + 1]['IP'] = $Invite['IP'];
  149. }
  150. }
  151. // Start page with current email
  152. ?>
  153. <div>
  154. <div class="header">
  155. <h2>Email history for <a href="user.php?id=<?=$UserID ?>"><?=$Username ?></a></h2>
  156. <div class="linkbox center">
  157. <a href="userhistory.php?action=email&amp;userid=<?=$UserID?>"
  158. class="brackets">Old email history</a>
  159. </div>
  160. </div>
  161. <br />
  162. <table width="100%">
  163. <tr class="colhead">
  164. <td>Current email</td>
  165. <td>Start</td>
  166. <td>End</td>
  167. <td>Current IP <a
  168. href="userhistory.php?action=ips&amp;userid=<?=$UserID ?>"
  169. class="brackets">H</a></td>
  170. <td>Set from IP</td>
  171. </tr>
  172. <?php
  173. $Current['Email'] = apcu_exists('DBKEY') ? Crypto::decrypt($Current['Email']) : '[Encrypted]';
  174. $Current['CurrentIP'] = apcu_exists('DBKEY') ? Crypto::decrypt($Current['CurrentIP']) : '[Encrypted]';
  175. $Current['IP'] = apcu_exists('DBKEY') ? Crypto::decrypt($Current['IP']) : '[Encrypted]';
  176. ?>
  177. <tr class="row">
  178. <td><?=display_str($Current['Email'])?>
  179. </td>
  180. <td><?=time_diff($Current['StartTime'])?>
  181. </td>
  182. <td></td>
  183. <td>
  184. <?=display_str($Current['CurrentIP'])?>
  185. <a href="user.php?action=search&amp;ip_history=on&amp;ip=<?=display_str($Current['CurrentIP'])?>"
  186. class="brackets tooltip" title="Search">S</a>
  187. <a href="http://whatismyipaddress.com/ip/<?=display_str($Current['CurrentIP'])?>"
  188. class="brackets tooltip" title="Search WIMIA.com">WI</a>
  189. <br />
  190. <?=Tools::get_host_by_ajax($Current['CurrentIP'])?>
  191. </td>
  192. <td>
  193. <?=display_str($Current['IP'])?>
  194. <a href="user.php?action=search&amp;ip_history=on&amp;ip=<?=display_str($Current['IP'])?>"
  195. class="brackets tooltip" title="Search">S</a>
  196. <a href="http://whatismyipaddress.com/ip/<?=display_str($Current['IP'])?>"
  197. class="brackets tooltip" title="Search WIMIA.com">WI</a>
  198. <br />
  199. <?=Tools::get_host_by_ajax($Current['IP'])?>
  200. </td>
  201. </tr>
  202. <?php
  203. if ($CurrentMatches ?? false) {
  204. // Match on the current email
  205. foreach ($CurrentMatches as $Match) {
  206. $Match['IP'] = apcu_exists('DBKEY') ? Crypto::decrypt($Match['IP']) : '[Encrypted]'; ?>
  207. <tr class="row">
  208. <td><?=$Match['Username']?>
  209. </td>
  210. <td></td>
  211. <td><?=time_diff($Match['EndTime'])?>
  212. </td>
  213. <td></td>
  214. <td>
  215. <?=display_str($Match['IP'])?>
  216. <a href="user.php?action=search&amp;ip_history=on&amp;ip=<?=display_str($Match['IP'])?>"
  217. class="brackets tooltip" title="Search">S</a>
  218. <a href="http://whatismyipaddress.com/ip/<?=display_str($Match['IP'])?>"
  219. class="brackets tooltip" title="Search WIMIA.com">WI</a>
  220. <br />
  221. <?=Tools::get_host_by_ajax($Match['IP'])?>
  222. </td>
  223. </tr>
  224. <?php
  225. }
  226. }
  227. // Old emails
  228. if ($Old ?? false) {
  229. ?>
  230. <tr class="colhead">
  231. <td>Old emails</td>
  232. <td>Start</td>
  233. <td>End</td>
  234. <td>Elapsed</td>
  235. <td>Set from IP</td>
  236. </tr>
  237. <?php
  238. $j = 0;
  239. // Old email
  240. foreach ($Old as $Record) {
  241. ++$j;
  242. // Matches on old email
  243. ob_start();
  244. $i = 0;
  245. if ($OldMatches ?? false) {
  246. foreach ($OldMatches as $Match) {
  247. if ($Match['Email'] == $Record['Email']) {
  248. ++$i;
  249. // Email matches
  250. ?>
  251. <tr class="row hidden" id="matches_<?=$j?>">
  252. <td><?=$Match['Username']?>
  253. </td>
  254. <td></td>
  255. <td><?=time_diff($Match['EndTime'])?>
  256. </td>
  257. <td></td>
  258. <td>
  259. <?=display_str($Match['IP'])?>
  260. <a href="user.php?action=search&amp;ip_history=on&amp;ip=<?=display_str($Match['IP'])?>"
  261. class="brackets tooltip" title="Search">S</a>
  262. <a href="http://whatismyipaddress.com/ip/<?=display_str($Match['IP'])?>"
  263. class="brackets tooltip" title="Search WIMIA.com">WI</a>
  264. <br />
  265. <?=Tools::get_host_by_ajax($Match['IP'])?>
  266. </td>
  267. </tr>
  268. <?php
  269. }
  270. }
  271. }
  272. // Save matches to variable
  273. $MatchCount = $i;
  274. $Matches = ob_get_contents();
  275. ob_end_clean();
  276. $Record['Email'] = apcu_exists('DBKEY') ? Crypto::decrypt($Record['Email']) : '[Encrypted]';
  277. $Record['IP'] = apcu_exists('DBKEY') ? Crypto::decrypt($Record['IP']) : '[Encrypted]'; ?>
  278. <tr class="row">
  279. <td><?=display_str($Record['Email'])?><?=(($MatchCount > 0) ? ' <a data-toggle-target="#matches_'.$j.'">('.$MatchCount.')</a>' : '')?>
  280. </td>
  281. <td><?=time_diff($Record['StartTime'])?>
  282. </td>
  283. <td><?=time_diff($Record['EndTime'])?>
  284. </td>
  285. <td><?=time_diff($Record['ElapsedTime'])?>
  286. </td>
  287. <td>
  288. <?=display_str($Record['IP'])?>
  289. <a href="user.php?action=search&amp;ip_history=on&amp;ip=<?=display_str($Record['IP'])?>"
  290. class="brackets tooltip" title="Search">S</a>
  291. <a href="http://whatismyipaddress.com/ip/<?=display_str($Record['IP'])?>"
  292. class="brackets tooltip" title="Search WIMIA.com">WI</a>
  293. <br />
  294. <?=Tools::get_host_by_ajax($Record['IP'])?>
  295. </td>
  296. </tr>
  297. <?php
  298. if ($MatchCount > 0) {
  299. if (isset($Matches)) {
  300. echo $Matches;
  301. unset($Matches);
  302. unset($MatchCount);
  303. }
  304. }
  305. }
  306. }
  307. // Invite email (always there)
  308. ?>
  309. <tr class="colhead">
  310. <td>Invite email</td>
  311. <td>Start</td>
  312. <td>End</td>
  313. <td>Age of account</td>
  314. <td>Registration IP address</td>
  315. </tr>
  316. <?php
  317. // Matches on invite email
  318. $i = 0;
  319. ob_start();
  320. if ($OldMatches ?? false) {
  321. foreach ($OldMatches as $Match) {
  322. if ($Match['Email'] == $Invite['Email']) {
  323. ++$i;
  324. // Match email is the same as the invite email
  325. $Match['IP'] = apcu_exists('DBKEY') ? Crypto::decrypt($Match['IP']) : '[Encrypted]'; ?>
  326. <tr class="row hidden" id="matches_invite">
  327. <td><?=$Match['Username']?>
  328. </td>
  329. <td></td>
  330. <td><?=time_diff($Match['EndTime'])?>
  331. </td>
  332. <td></td>
  333. <td>
  334. <?=display_str($Match['IP'])?>
  335. <a href="user.php?action=search&amp;ip_history=on&amp;ip=<?=display_str($Match['IP'])?>"
  336. class="brackets tooltip" title="Search">S</a>
  337. <a href="http://whatismyipaddress.com/ip/<?=display_str($Match['IP'])?>"
  338. class="brackets tooltip" title="Search WIMIA.com">WI</a>
  339. <br />
  340. <?=Tools::get_host_by_ajax($Match['IP'])?>
  341. </td>
  342. </tr>
  343. <?php
  344. }
  345. }
  346. }
  347. $MatchCount = $i;
  348. $Matches = ob_get_contents();
  349. ob_end_clean();
  350. $Invite['Email'] = apcu_exists('DBKEY') ? Crypto::decrypt($Invite['Email']) : '[Encrypted]';
  351. $Invite['IP'] = apcu_exists('DBKEY') ? Crypto::decrypt($Invite['IP']) : '[Encrypted]';
  352. ?>
  353. <tr class="row">
  354. <td><?=display_str($Invite['Email'])?><?=(($MatchCount > 0) ? ' <a data-toggle-target="#matches_invite">('.$MatchCount.')</a>' : '')?>
  355. </td>
  356. <td>Never</td>
  357. <td><?=time_diff($Invite['EndTime'])?>
  358. </td>
  359. <td><?=time_diff($Invite['AccountAge'])?>
  360. </td>
  361. <td>
  362. <?=display_str($Invite['IP'])?>
  363. <a href="user.php?action=search&amp;ip_history=on&amp;ip=<?=display_str($Invite['IP'])?>"
  364. class="brackets tooltip" title="Search">S</a>
  365. <a href="http://whatismyipaddress.com/ip/<?=display_str($Invite['IP'])?>"
  366. class="brackets tooltip" title="Search WIMIA.com">WI</a>
  367. <br />
  368. <?=Tools::get_host_by_ajax($Invite['IP'])?>
  369. </td>
  370. </tr>
  371. <?php
  372. if ($Matches) {
  373. echo $Matches;
  374. }
  375. ?>
  376. </table>
  377. </div>
  378. <?php View::show_footer();