InfoController.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controllers\User;
  4. use App\Controllers\BaseController;
  5. use App\Models\Config;
  6. use App\Models\User;
  7. use App\Services\Auth;
  8. use App\Services\Cache;
  9. use App\Services\MFA;
  10. use App\Utils\Hash;
  11. use App\Utils\ResponseHelper;
  12. use App\Utils\Tools;
  13. use Exception;
  14. use Psr\Http\Message\ResponseInterface;
  15. use Ramsey\Uuid\Uuid;
  16. use RedisException;
  17. use Slim\Http\Response;
  18. use Slim\Http\ServerRequest;
  19. use voku\helper\AntiXSS;
  20. use function in_array;
  21. use function strlen;
  22. use function strtolower;
  23. use const BASE_PATH;
  24. final class InfoController extends BaseController
  25. {
  26. /**
  27. * @throws Exception
  28. */
  29. public function index(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
  30. {
  31. $themes = Tools::getDir(BASE_PATH . '/resources/views');
  32. $methods = Tools::getSsMethod('method');
  33. $ga_url = MFA::getGaUrl($this->user);
  34. return $response->write($this->view()
  35. ->assign('user', $this->user)
  36. ->assign('themes', $themes)
  37. ->assign('methods', $methods)
  38. ->assign('ga_url', $ga_url)
  39. ->fetch('user/edit.tpl'));
  40. }
  41. /**
  42. * @throws RedisException
  43. */
  44. public function updateEmail(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
  45. {
  46. $antiXss = new AntiXSS();
  47. $new_email = $antiXss->xss_clean($request->getParam('newemail'));
  48. $user = $this->user;
  49. $old_email = $user->email;
  50. if (! $_ENV['enable_change_email'] || $user->is_shadow_banned) {
  51. return ResponseHelper::error($response, '修改失败');
  52. }
  53. if ($new_email === '') {
  54. return ResponseHelper::error($response, '未填写邮箱');
  55. }
  56. $check_res = Tools::isEmailLegal($new_email);
  57. if ($check_res['ret'] !== 1) {
  58. return $response->withJson($check_res);
  59. }
  60. $exist_user = (new User())->where('email', $new_email)->first();
  61. if ($exist_user !== null) {
  62. return ResponseHelper::error($response, '邮箱已经被使用了');
  63. }
  64. if ($new_email === $old_email) {
  65. return ResponseHelper::error($response, '新邮箱不能和旧邮箱一样');
  66. }
  67. if (Config::obtain('reg_email_verify')) {
  68. $redis = (new Cache())->initRedis();
  69. $email_verify_code = $request->getParam('emailcode');
  70. $email_verify = $redis->get('email_verify:' . $email_verify_code);
  71. if (! $email_verify) {
  72. return ResponseHelper::error($response, '你的邮箱验证码不正确');
  73. }
  74. $redis->del('email_verify:' . $email_verify_code);
  75. }
  76. $user->email = $new_email;
  77. if (! $user->save()) {
  78. return ResponseHelper::error($response, '修改失败');
  79. }
  80. return $response->withJson([
  81. 'ret' => 1,
  82. 'msg' => '修改成功',
  83. 'data' => [
  84. 'email' => $user->email,
  85. ],
  86. ]);
  87. }
  88. public function updateUsername(ServerRequest $request, Response $response, array $args): ResponseInterface
  89. {
  90. $antiXss = new AntiXSS();
  91. $newusername = $antiXss->xss_clean($request->getParam('newusername'));
  92. $user = $this->user;
  93. if ($user->is_shadow_banned) {
  94. return ResponseHelper::error($response, '修改失败');
  95. }
  96. $user->user_name = $newusername;
  97. if (! $user->save()) {
  98. return ResponseHelper::error($response, '修改失败');
  99. }
  100. return $response->withJson([
  101. 'ret' => 1,
  102. 'msg' => '修改成功',
  103. 'data' => [
  104. 'username' => $user->user_name,
  105. ],
  106. ]);
  107. }
  108. public function unbindIM(ServerRequest $request, Response $response, array $args): ResponseInterface
  109. {
  110. $user = $this->user;
  111. if (! $user->unbindIM()) {
  112. return ResponseHelper::error($response, '解绑失败');
  113. }
  114. return $response->withHeader('HX-Refresh', 'true')->withJson([
  115. 'ret' => 1,
  116. 'msg' => '解绑成功',
  117. ]);
  118. }
  119. public function updatePassword(ServerRequest $request, Response $response, array $args): ResponseInterface
  120. {
  121. $oldpwd = $request->getParam('oldpwd');
  122. $pwd = $request->getParam('pwd');
  123. $repwd = $request->getParam('repwd');
  124. $user = $this->user;
  125. if ($oldpwd === '' || $pwd === '' || $repwd === '') {
  126. return ResponseHelper::error($response, '密码不能为空');
  127. }
  128. if (! Hash::checkPassword($user->pass, $oldpwd)) {
  129. return ResponseHelper::error($response, '旧密码错误');
  130. }
  131. if ($pwd !== $repwd) {
  132. return ResponseHelper::error($response, '两次输入不符合');
  133. }
  134. if (strlen($pwd) < 8) {
  135. return ResponseHelper::error($response, '密码太短啦');
  136. }
  137. if (! $user->updatePassword($pwd)) {
  138. return ResponseHelper::error($response, '修改失败');
  139. }
  140. if (Config::obtain('enable_forced_replacement')) {
  141. $user->cleanLink();
  142. }
  143. return ResponseHelper::success($response, '修改成功');
  144. }
  145. public function resetPasswd(ServerRequest $request, Response $response, array $args): ResponseInterface
  146. {
  147. $user = $this->user;
  148. $user->passwd = Tools::genRandomChar(16);
  149. $user->uuid = Uuid::uuid4();
  150. if (! $user->save()) {
  151. return ResponseHelper::error($response, '重置失败');
  152. }
  153. return $response->withJson([
  154. 'ret' => 1,
  155. 'msg' => '重置成功',
  156. 'data' => [
  157. 'passwd' => $user->passwd,
  158. 'uuid' => $user->uuid,
  159. ],
  160. ]);
  161. }
  162. public function resetApiToken(ServerRequest $request, Response $response, array $args): ResponseInterface
  163. {
  164. $user = $this->user;
  165. $user->api_token = Uuid::uuid4();
  166. if (! $user->save()) {
  167. return ResponseHelper::error($response, '重置失败');
  168. }
  169. return ResponseHelper::success($response, '重置成功');
  170. }
  171. public function updateMethod(ServerRequest $request, Response $response, array $args): ResponseInterface
  172. {
  173. $antiXss = new AntiXSS();
  174. $user = $this->user;
  175. $method = strtolower($antiXss->xss_clean($request->getParam('method')));
  176. if ($method === '') {
  177. ResponseHelper::error($response, '非法输入');
  178. }
  179. if (! Tools::isParamValidate('method', $method)) {
  180. ResponseHelper::error($response, '加密无效');
  181. }
  182. $user->method = $method;
  183. if (! $user->save()) {
  184. return ResponseHelper::error($response, '修改失败');
  185. }
  186. return ResponseHelper::success($response, '修改成功');
  187. }
  188. public function resetURL(ServerRequest $request, Response $response, array $args): ResponseInterface
  189. {
  190. $user = $this->user;
  191. $user->cleanLink();
  192. return ResponseHelper::success($response, '重置成功');
  193. }
  194. public function resetInviteURL(ServerRequest $request, Response $response, array $args): ResponseInterface
  195. {
  196. $user = $this->user;
  197. $user->clearInviteCodes();
  198. $code = $this->user->addInviteCode();
  199. return $response->withJson([
  200. 'ret' => 1,
  201. 'msg' => '重置成功',
  202. 'data' => [
  203. 'invite-url' => $_ENV['baseUrl'] . '/auth/register?code=' . $code,
  204. ],
  205. ]);
  206. }
  207. public function updateDailyMail(ServerRequest $request, Response $response, array $args): ResponseInterface
  208. {
  209. $value = (int) $request->getParam('mail');
  210. if (! in_array($value, [0, 1, 2])) {
  211. return ResponseHelper::error($response, '参数错误');
  212. }
  213. $user = $this->user;
  214. $user->daily_mail_enable = $value;
  215. if (! $user->save()) {
  216. return ResponseHelper::error($response, '修改失败');
  217. }
  218. return ResponseHelper::success($response, '修改成功');
  219. }
  220. public function updateContactMethod(ServerRequest $request, Response $response, array $args): ResponseInterface
  221. {
  222. $value = (int) $request->getParam('contact');
  223. if (! in_array($value, [1, 2])) {
  224. return ResponseHelper::error($response, '参数错误');
  225. }
  226. $user = $this->user;
  227. $user->contact_method = $value;
  228. if (! $user->save()) {
  229. return ResponseHelper::error($response, '修改失败');
  230. }
  231. return ResponseHelper::success($response, '修改成功');
  232. }
  233. public function updateTheme(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
  234. {
  235. $antiXss = new AntiXSS();
  236. $theme = $antiXss->xss_clean($request->getParam('theme'));
  237. $user = $this->user;
  238. if ($theme === '') {
  239. return ResponseHelper::error($response, '主题不能为空');
  240. }
  241. $user->theme = $theme;
  242. if (! $user->save()) {
  243. return ResponseHelper::error($response, '修改失败');
  244. }
  245. return $response->withHeader('HX-Refresh', 'true')->withJson([
  246. 'ret' => 1,
  247. 'msg' => '修改成功',
  248. ]);
  249. }
  250. public function sendToGulag(ServerRequest $request, Response $response, array $args): ResponseInterface
  251. {
  252. $user = $this->user;
  253. $passwd = $request->getParam('passwd');
  254. if ($passwd === '') {
  255. return ResponseHelper::error($response, '密码不能为空');
  256. }
  257. if (! Hash::checkPassword($user->pass, $passwd)) {
  258. return ResponseHelper::error($response, '密码错误');
  259. }
  260. if ($_ENV['enable_kill']) {
  261. Auth::logout();
  262. $user->kill();
  263. return $response->withHeader('HX-Refresh', 'true')->withJson([
  264. 'ret' => 1,
  265. 'msg' => '你的帐号已被送去古拉格劳动改造,再见',
  266. ]);
  267. }
  268. return ResponseHelper::error($response, '自助账号删除未启用');
  269. }
  270. }