Oppaitime'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.

take_edit.php 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. <?
  2. authorize();
  3. $UserID = $_REQUEST['userid'];
  4. if (!is_number($UserID)) {
  5. error(404);
  6. }
  7. //For this entire page, we should generally be using $UserID not $LoggedUser['ID'] and $U[] not $LoggedUser[]
  8. $U = Users::user_info($UserID);
  9. if (!$U) {
  10. error(404);
  11. }
  12. $Permissions = Permissions::get_permissions($U['PermissionID']);
  13. if ($UserID != $LoggedUser['ID'] && !check_perms('users_edit_profiles', $Permissions['Class'])) {
  14. send_irc('PRIVMSG '.ADMIN_CHAN.' :User '.$LoggedUser['Username'].' ('.site_url().'user.php?id='.$LoggedUser['ID'].') just tried to edit the profile of '.site_url().'user.php?id='.$_REQUEST['userid']);
  15. error(403);
  16. }
  17. $Val->SetFields('stylesheet', 1, "number", "You forgot to select a stylesheet.");
  18. $Val->SetFields('styleurl', 0, "regex", "You did not enter a valid stylesheet URL.", ['regex' => '/^'.CSS_REGEX.'$/i']);
  19. // The next two are commented out because the drop-down menus were replaced with a check box and radio buttons
  20. //$Val->SetFields('disablegrouping', 0, "number", "You forgot to select your torrent grouping option.");
  21. //$Val->SetFields('torrentgrouping', 0, "number", "You forgot to select your torrent grouping option.");
  22. $Val->SetFields('postsperpage', 1, "number", "You forgot to select your posts per page option.", ['inarray' => [25, 50, 100]]);
  23. //$Val->SetFields('hidecollage', 1, "number", "You forgot to select your collage option.", ['minlength' => 0, 'maxlength' => 1]);
  24. $Val->SetFields('collagecovers', 1, "number", "You forgot to select your collage option.");
  25. $Val->SetFields('avatar', 0, "regex", "You did not enter a valid avatar URL.", ['regex' => "/^".IMAGE_REGEX."$/i"]);
  26. $Val->SetFields('email', 1, "email", "You did not enter a valid email address.");
  27. $Val->SetFields('twofa', 0, "regex", "You did not enter a valid 2FA verification code.", ['regex' => '/^[0-9]{6}$/']);
  28. $Val->SetFields('irckey', 0, "string", "You did not enter a valid IRC key. An IRC key must be between 6 and 32 characters long.", ['minlength' => 6, 'maxlength' => 32]);
  29. $Val->SetFields('new_pass_1', 0, "regex", "You did not enter a valid password. A valid password is 6 characters or longer.", ['regex' => '/(?=^.{6,}$).*$/']);
  30. $Val->SetFields('new_pass_2', 1, "compare", "Your passwords do not match.", ['comparefield' => 'new_pass_1']);
  31. if (check_perms('site_advanced_search')) {
  32. $Val->SetFields('searchtype', 1, "number", "You forgot to select your default search preference.", ['minlength' => 0, 'maxlength' => 1]);
  33. }
  34. $Err = $Val->ValidateForm($_POST);
  35. if (!apcu_exists('DBKEY')) {
  36. $Err = "Cannot edit profile until database fully decrypted.";
  37. }
  38. if ($Err) {
  39. error($Err);
  40. header("Location: user.php?action=edit&userid=$UserID");
  41. die();
  42. }
  43. // Begin building $Paranoia
  44. // Reduce the user's input paranoia until it becomes consistent
  45. if (isset($_POST['p_uniquegroups_l'])) {
  46. $_POST['p_uploads_l'] = 'on';
  47. $_POST['p_uploads_c'] = 'on';
  48. }
  49. if (isset($_POST['p_uploads_l'])) {
  50. $_POST['p_uniquegroups_l'] = 'on';
  51. $_POST['p_uniquegroups_c'] = 'on';
  52. $_POST['p_perfectflacs_l'] = 'on';
  53. $_POST['p_perfectflacs_c'] = 'on';
  54. $_POST['p_artistsadded'] = 'on';
  55. }
  56. if (isset($_POST['p_collagecontribs_l'])) {
  57. $_POST['p_collages_l'] = 'on';
  58. $_POST['p_collages_c'] = 'on';
  59. }
  60. if (isset($_POST['p_snatched_c']) && isset($_POST['p_seeding_c']) && isset($_POST['p_downloaded'])) {
  61. $_POST['p_requiredratio'] = 'on';
  62. }
  63. // if showing exactly 2 of stats, show all 3 of stats
  64. $StatsShown = 0;
  65. $Stats = ['downloaded', 'uploaded', 'ratio'];
  66. foreach ($Stats as $S) {
  67. if (isset($_POST["p_$S"])) {
  68. $StatsShown++;
  69. }
  70. }
  71. if ($StatsShown == 2) {
  72. foreach ($Stats as $S) {
  73. $_POST["p_$S"] = 'on';
  74. }
  75. }
  76. $Paranoia = [];
  77. $Checkboxes = ['downloaded', 'uploaded', 'ratio', 'lastseen', 'requiredratio', 'invitedcount', 'artistsadded', 'notifications'];
  78. foreach ($Checkboxes as $C) {
  79. if (!isset($_POST["p_$C"])) {
  80. $Paranoia[] = $C;
  81. }
  82. }
  83. $SimpleSelects = ['torrentcomments', 'collages', 'collagecontribs', 'uploads', 'uniquegroups', 'perfectflacs', 'seeding', 'leeching', 'snatched'];
  84. foreach ($SimpleSelects as $S) {
  85. if (!isset($_POST["p_$S".'_c']) && !isset($_POST["p_$S".'_l'])) {
  86. // Very paranoid - don't show count or list
  87. $Paranoia[] = "$S+";
  88. } elseif (!isset($_POST["p_$S".'_l'])) {
  89. // A little paranoid - show count, don't show list
  90. $Paranoia[] = $S;
  91. }
  92. }
  93. $Bounties = ['requestsfilled', 'requestsvoted'];
  94. foreach ($Bounties as $B) {
  95. if (isset($_POST["p_$B".'_list'])) {
  96. $_POST["p_$B".'_count'] = 'on';
  97. $_POST["p_$B".'_bounty'] = 'on';
  98. }
  99. if (!isset($_POST["p_$B".'_list'])) {
  100. $Paranoia[] = $B.'_list';
  101. }
  102. if (!isset($_POST["p_$B".'_count'])) {
  103. $Paranoia[] = $B.'_count';
  104. }
  105. if (!isset($_POST["p_$B".'_bounty'])) {
  106. $Paranoia[] = $B.'_bounty';
  107. }
  108. }
  109. if (!isset($_POST['p_donor_heart'])) {
  110. $Paranoia[] = 'hide_donor_heart';
  111. }
  112. if (isset($_POST['p_donor_stats'])) {
  113. Donations::show_stats($UserID);
  114. } else {
  115. Donations::hide_stats($UserID);
  116. }
  117. // End building $Paranoia
  118. // Email change
  119. $DB->query("
  120. SELECT Email
  121. FROM users_main
  122. WHERE ID = $UserID");
  123. list($CurEmail) = $DB->next_record();
  124. $CurEmail = DBCrypt::decrypt($CurEmail);
  125. if ($CurEmail != $_POST['email']) {
  126. if (!check_perms('users_edit_profiles')) { // Non-admins have to authenticate to change email
  127. $DB->query("
  128. SELECT PassHash
  129. FROM users_main
  130. WHERE ID = '".db_string($UserID)."'");
  131. list($PassHash)=$DB->next_record();
  132. if (!Users::check_password($_POST['cur_pass'], $PassHash)) {
  133. $Err = 'You did not enter the correct password.';
  134. }
  135. }
  136. if (!$Err) {
  137. $NewEmail = db_string($_POST['email']);
  138. //This piece of code will update the time of their last email change to the current time *not* the current change.
  139. $ChangerIP = db_string($LoggedUser['IP']);
  140. $DB->query("
  141. UPDATE users_history_emails
  142. SET Time = '".sqltime()."'
  143. WHERE UserID = '$UserID'
  144. AND Time IS NULL");
  145. $DB->query("
  146. INSERT INTO users_history_emails
  147. (UserID, Email, Time, IP)
  148. VALUES
  149. ('$UserID', '".DBCrypt::encrypt($NewEmail)."', NULL, '".DBCrypt::encrypt($_SERVER['REMOTE_ADDR'])."')");
  150. } else {
  151. error($Err);
  152. header("Location: user.php?action=edit&userid=$UserID");
  153. die();
  154. }
  155. }
  156. //End email change
  157. //2FA activation
  158. if (!empty($_POST['twofa'])) {
  159. $DB->query("
  160. SELECT TwoFactor, PassHash
  161. FROM users_main
  162. WHERE ID = $UserID");
  163. list($TwoFactor, $PassHash) = $DB->next_record();
  164. if (empty($TwoFactor)) {
  165. if (!Users::check_password($_POST['cur_pass'], $PassHash)) {
  166. error('You did not enter the correct password.');
  167. header("Location: user.php?action=edit&userid=$UserID");
  168. die();
  169. }
  170. require_once SERVER_ROOT.'/classes/twofa.class.php';
  171. $TwoFA = new TwoFactorAuth(SITE_NAME);
  172. if ($TwoFA->verifyCode($_POST['twofasecret'], $_POST['twofa'])) {
  173. $DB->query("
  174. UPDATE users_main
  175. SET TwoFactor='".db_string($_POST['twofasecret'])."'
  176. WHERE ID = $UserID");
  177. } else {
  178. error('Invalid 2FA verification code.');
  179. header("Location: user.php?action=edit&userid=$UserID");
  180. die();
  181. }
  182. }
  183. }
  184. //2FA deactivation
  185. if (isset($_POST['disable2fa'])) {
  186. $DB->query("
  187. SELECT PassHash
  188. FROM users_main
  189. WHERE ID = $UserID");
  190. list($PassHash) = $DB->next_record();
  191. if (!Users::check_password($_POST['cur_pass'], $PassHash)) {
  192. error('You did not enter the correct password.');
  193. header("Location: user.php?action=edit&userid=$UserID");
  194. die();
  195. }
  196. $DB->query("
  197. UPDATE users_main
  198. SET TwoFactor=NULL
  199. WHERE ID = $UserID");
  200. }
  201. //End 2FA
  202. if (!$Err && ($_POST['cur_pass'] || $_POST['new_pass_1'] || $_POST['new_pass_2'])) {
  203. $DB->query("
  204. SELECT PassHash
  205. FROM users_main
  206. WHERE ID = '".db_string($UserID)."'");
  207. list($PassHash) = $DB->next_record();
  208. if (Users::check_password($_POST['cur_pass'], $PassHash)) {
  209. if ($_POST['new_pass_1'] && $_POST['new_pass_2']) {
  210. $ResetPassword = true;
  211. }
  212. } else {
  213. $Err = 'You did not enter the correct password.';
  214. }
  215. }
  216. if ($LoggedUser['DisableAvatar'] && $_POST['avatar'] != $U['Avatar']) {
  217. $Err = 'Your avatar privileges have been revoked.';
  218. }
  219. if ($Err) {
  220. error($Err);
  221. header("Location: user.php?action=edit&userid=$UserID");
  222. die();
  223. }
  224. if (!empty($LoggedUser['DefaultSearch'])) {
  225. $Options['DefaultSearch'] = $LoggedUser['DefaultSearch'];
  226. }
  227. $Options['DisableGrouping2'] = (!empty($_POST['disablegrouping']) ? 0 : 1);
  228. $Options['TorrentGrouping'] = (!empty($_POST['torrentgrouping']) ? 1 : 0);
  229. $Options['PostsPerPage'] = (int)$_POST['postsperpage'];
  230. $Options['CollageCovers'] = (empty($_POST['collagecovers']) ? 0 : $_POST['collagecovers']);
  231. $Options['ShowTorFilter'] = (empty($_POST['showtfilter']) ? 0 : 1);
  232. $Options['ShowTags'] = (!empty($_POST['showtags']) ? 1 : 0);
  233. $Options['AutoSubscribe'] = (!empty($_POST['autosubscribe']) ? 1 : 0);
  234. $Options['DisableSmileys'] = (!empty($_POST['disablesmileys']) ? 1 : 0);
  235. $Options['AutoloadCommStats'] = (check_perms('users_mod') && !empty($_POST['autoload_comm_stats']) ? 1 : 0);
  236. $Options['DisableAvatars'] = db_string($_POST['disableavatars']);
  237. $Options['Identicons'] = (!empty($_POST['identicons']) ? (int)$_POST['identicons'] : 0);
  238. $Options['DisablePMAvatars'] = (!empty($_POST['disablepmavatars']) ? 1 : 0);
  239. $Options['NotifyOnQuote'] = (!empty($_POST['notifications_Quotes_popup']) ? 1 : 0);
  240. $Options['ListUnreadPMsFirst'] = (!empty($_POST['list_unread_pms_first']) ? 1 : 0);
  241. $Options['ShowSnatched'] = (!empty($_POST['showsnatched']) ? 1 : 0);
  242. $Options['ShowMagnets'] = (!empty($_POST['showmagnets']) ? 1 : 0);
  243. $Options['DisableAutoSave'] = (!empty($_POST['disableautosave']) ? 1 : 0);
  244. $Options['CoverArt'] = (int)!empty($_POST['coverart']);
  245. $Options['ShowExtraCovers'] = (int)!empty($_POST['show_extra_covers']);
  246. $Options['HideLolicon'] = (int)!empty($_POST['hide_lolicon']);
  247. $Options['HideScat'] = (int)!empty($_POST['hide_scat']);
  248. $Options['HideSnuff'] = (int)!empty($_POST['hide_snuff']);
  249. $Options['AutoComplete'] = (int)$_POST['autocomplete'];
  250. $Options['StyleAdditions'] = $_POST['style_additions'] ?? [];
  251. if (isset($LoggedUser['DisableFreeTorrentTop10'])) {
  252. $Options['DisableFreeTorrentTop10'] = $LoggedUser['DisableFreeTorrentTop10'];
  253. }
  254. if (!empty($_POST['sorthide'])) {
  255. $JSON = json_decode($_POST['sorthide']);
  256. foreach ($JSON as $J) {
  257. $E = explode('_', $J);
  258. $Options['SortHide'][$E[0]] = $E[1];
  259. }
  260. } else {
  261. $Options['SortHide'] = [];
  262. }
  263. if (check_perms('site_advanced_search')) {
  264. $Options['SearchType'] = $_POST['searchtype'];
  265. } else {
  266. unset($Options['SearchType']);
  267. }
  268. //TODO: Remove the following after a significant amount of time
  269. unset($Options['ArtistNoRedirect']);
  270. unset($Options['ShowQueryList']);
  271. unset($Options['ShowCacheList']);
  272. $UnseededAlerts = isset($_POST['unseededalerts']) ? 1 : 0;
  273. Donations::update_rewards($UserID);
  274. NotificationsManager::save_settings($UserID);
  275. // Begin Badge settings
  276. if (!empty($_POST['badges'])) {
  277. $BadgeIDs = array_slice($_POST['badges'], 0, 5);
  278. } else {
  279. $BadgeIDs = [];
  280. }
  281. $BadgesChanged = false;
  282. $NewBadges = [];
  283. if ($Cache->get_value('user_badges_'.$UserID)) {
  284. $Badges = $Cache->get_value('user_badges_'.$UserID);
  285. foreach ($Badges as $Badge) {
  286. if (in_array($Badge['BadgeID'], $BadgeIDs)) { // Is the current badge in the list of badges the user wants to display?
  287. $Displayed = true;
  288. $DisplayedBadgeIDs[] = $Badge['BadgeID'];
  289. if ($Badge['Displayed'] == 0) { // The user wants to display a badge that wasn't displayed before
  290. $BadgesChanged = true;
  291. }
  292. } else { // The user no longer wants to display a badge that was displayed before
  293. $Displayed = false;
  294. $BadgesChanged = true;
  295. }
  296. $NewBadges[] = ['BadgeID' => $Badge['BadgeID'], 'Displayed' => $Displayed?'1':'0'];
  297. }
  298. } else {
  299. $BadgesChanged = true;
  300. }
  301. if ($BadgesChanged) {
  302. $Cache->cache_value('user_badges_'.$UserID, $NewBadges);
  303. }
  304. // End Badge settings
  305. $Cache->begin_transaction("user_info_$UserID");
  306. $Cache->update_row(false, [
  307. 'Avatar' => display_str($_POST['avatar']),
  308. 'Paranoia' => $Paranoia
  309. ]);
  310. $Cache->commit_transaction(0);
  311. $Cache->begin_transaction("user_info_heavy_$UserID");
  312. $Cache->update_row(false, [
  313. 'StyleID' => $_POST['stylesheet'],
  314. 'StyleURL' => display_str($_POST['styleurl'])
  315. ]);
  316. $Cache->update_row(false, $Options);
  317. $Cache->commit_transaction(0);
  318. $SQL = "
  319. UPDATE users_main AS m
  320. JOIN users_info AS i ON m.ID = i.UserID
  321. SET
  322. i.StyleID = '".db_string($_POST['stylesheet'])."',
  323. i.StyleURL = '".db_string($_POST['styleurl'])."',
  324. i.Avatar = '".db_string($_POST['avatar'])."',
  325. i.SiteOptions = '".db_string(json_encode($Options))."',
  326. i.NotifyOnQuote = '".db_string($Options['NotifyOnQuote'])."',
  327. i.Info = '".db_string($_POST['info'])."',
  328. i.InfoTitle = '".db_string($_POST['profile_title'])."',
  329. i.UnseededAlerts = '$UnseededAlerts',
  330. m.Email = '".DBCrypt::encrypt($_POST['email'])."',
  331. m.IRCKey = '".db_string($_POST['irckey'])."',
  332. m.Paranoia = '".db_string(json_encode($Paranoia))."'";
  333. if ($ResetPassword) {
  334. $ChangerIP = db_string(DBCrypt::encrypt($LoggedUser['IP']));
  335. $PassHash = Users::make_sec_hash($_POST['new_pass_1']);
  336. $SQL.= ",m.PassHash = '".db_string($PassHash)."'";
  337. $DB->query("
  338. INSERT INTO users_history_passwords
  339. (UserID, ChangerIP, ChangeTime)
  340. VALUES
  341. ('$UserID', '$ChangerIP', '".sqltime()."')");
  342. }
  343. if (isset($_POST['resetpasskey'])) {
  344. $UserInfo = Users::user_heavy_info($UserID);
  345. $OldPassKey = db_string($UserInfo['torrent_pass']);
  346. $NewPassKey = db_string(Users::make_secret());
  347. $ChangerIP = db_string(DBCrypt::encrypt($LoggedUser['IP']));
  348. $SQL .= ",m.torrent_pass = '$NewPassKey'";
  349. $DB->query("
  350. INSERT INTO users_history_passkeys
  351. (UserID, OldPassKey, NewPassKey, ChangerIP, ChangeTime)
  352. VALUES
  353. ('$UserID', '$OldPassKey', '$NewPassKey', '$ChangerIP', '".sqltime()."')");
  354. $Cache->begin_transaction("user_info_heavy_$UserID");
  355. $Cache->update_row(false, ['torrent_pass' => $NewPassKey]);
  356. $Cache->commit_transaction(0);
  357. $Cache->delete_value("user_$OldPassKey");
  358. Tracker::update_tracker('change_passkey', ['oldpasskey' => $OldPassKey, 'newpasskey' => $NewPassKey]);
  359. }
  360. $SQL .= "WHERE m.ID = '".db_string($UserID)."'";
  361. $DB->query($SQL);
  362. if ($BadgesChanged) {
  363. $DB->query("
  364. UPDATE users_badges
  365. SET Displayed = 0
  366. WHERE UserID = $UserID");
  367. if (!empty($BadgeIDs)) {
  368. $DB->query("
  369. UPDATE users_badges
  370. SET Displayed = 1
  371. WHERE UserID = $UserID
  372. AND BadgeID IN (".db_string(implode(',', $BadgeIDs)).")");
  373. }
  374. }
  375. if ($ResetPassword) {
  376. logout_all_sessions();
  377. }
  378. header("Location: user.php?action=edit&userid=$UserID");
  379. ?>