Просмотр файла app/Http/Controllers/User/UserController.php

Размер файла: 34.76Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Http\Controllers\User;
  6.  
  7. use App\Classes\Validator;
  8. use App\Http\Controllers\Controller;
  9. use App\Models\BlackList;
  10. use App\Models\ChangeMail;
  11. use App\Models\Flood;
  12. use App\Models\Invite;
  13. use App\Models\User;
  14. use App\Models\UserField;
  15. use Exception;
  16. use GuzzleHttp\Exception\GuzzleException;
  17. use Illuminate\Database\Query\JoinClause;
  18. use Illuminate\Http\JsonResponse;
  19. use Illuminate\Http\RedirectResponse;
  20. use Illuminate\Support\Facades\DB;
  21. use Illuminate\Http\Request;
  22. use Illuminate\Support\Str;
  23. use Illuminate\View\View;
  24.  
  25. class UserController extends Controller
  26. {
  27. /**
  28. * User profile
  29. *
  30. * @param string $login
  31. *
  32. * @return View
  33. */
  34. public function index(string $login): View
  35. {
  36. if (! $user = getUserByLogin($login)) {
  37. abort(404, __('validator.user'));
  38. }
  39.  
  40. $user->load('lastBan');
  41. $adminGroups = User::ADMIN_GROUPS;
  42. $invite = Invite::query()->where('invite_user_id', $user->id)->first();
  43.  
  44. $fields = UserField::query()
  45. ->select('uf.*', 'ud.value')
  46. ->from('user_fields as uf')
  47. ->leftJoin('user_data as ud', static function (JoinClause $join) use ($user) {
  48. $join->on('uf.id', 'ud.field_id')
  49. ->where('ud.user_id', $user->id);
  50. })
  51. ->whereNotNull('ud.value')
  52. ->orderBy('uf.sort')
  53. ->get();
  54.  
  55. return view('users/user', compact('user', 'invite', 'adminGroups', 'fields'));
  56. }
  57.  
  58. /**
  59. * Note
  60. *
  61. * @param string $login
  62. * @param Request $request
  63. * @param Validator $validator
  64. *
  65. * @return View|RedirectResponse
  66. */
  67. public function note(string $login, Request $request, Validator $validator)
  68. {
  69. if (! isAdmin()) {
  70. abort(403, __('main.page_only_admins'));
  71. }
  72.  
  73. if (! $user = getUserByLogin($login)) {
  74. abort(404, __('validator.user'));
  75. }
  76.  
  77. if ($request->isMethod('post')) {
  78. $notice = $request->input('notice');
  79.  
  80. $validator->equal($request->input('_token'), csrf_token(), ['notice' => __('validator.token')])
  81. ->length($notice, 0, 1000, ['notice' => __('users.note_to_big')]);
  82.  
  83. if ($validator->isValid()) {
  84. $user->note()->updateOrCreate([], [
  85. 'text' => $notice,
  86. 'edit_user_id' => getUser('id'),
  87. 'updated_at' => SITETIME,
  88. ]);
  89.  
  90. setFlash('success', __('users.note_saved_success'));
  91.  
  92. return redirect('users/' . $user->login);
  93. }
  94.  
  95. setInput($request->all());
  96. setFlash('danger', $validator->getErrors());
  97. }
  98.  
  99. return view('users/note', compact('user'));
  100. }
  101.  
  102. /**
  103. * Registration
  104. *
  105. * @param Request $request
  106. * @param Validator $validator
  107. *
  108. * @return View|RedirectResponse
  109. * @throws GuzzleException
  110. */
  111. public function register(Request $request, Validator $validator)
  112. {
  113. if (getUser()) {
  114. abort(403, __('users.already_registered'));
  115. }
  116.  
  117. if (! setting('openreg')) {
  118. abort(200, __('users.registration_suspended'));
  119. }
  120.  
  121. if ($request->isMethod('post')) {
  122. if ($request->has(['login', 'password'])) {
  123. $login = $request->input('login');
  124. $password = $request->input('password');
  125. $password2 = $request->input('password2');
  126. $invite = setting('invite') ? $request->input('invite') : '';
  127. $email = strtolower($request->input('email'));
  128. $domain = utfSubstr(strrchr($email, '@'), 1);
  129. $gender = $request->input('gender') === User::MALE ? User::MALE : User::FEMALE;
  130. $level = User::USER;
  131. $activateLink = null;
  132. $activateKey = null;
  133. $invitation = null;
  134.  
  135. $validator->true(captchaVerify(), ['protect' => __('validator.captcha')])
  136. ->regex($login, '|^[a-z0-9\-]+$|i', ['login' => __('validator.login')])
  137. ->regex(utfSubstr($login, 0, 1), '|^[a-z0-9]+$|i', ['login' => __('users.login_begin_requirements')])
  138. ->email($email, ['email' => __('validator.email')])
  139. ->length($invite, 12, 16, ['invite' => __('users.invite_length_requirements')], (bool) setting('invite'))
  140. ->length($login, 3, 20, ['login' => __('users.login_length_requirements')])
  141. ->length($password, 6, 20, ['password' => __('users.password_length_requirements')])
  142. ->equal($password, $password2, ['password2' => __('users.passwords_different')])
  143. ->false(ctype_digit($login), ['login' => __('users.field_characters_requirements')])
  144. ->false(ctype_digit($password), ['password' => __('users.field_characters_requirements')])
  145. ->false(substr_count($login, '-') > 2, ['login' => __('users.login_hyphens_requirements')]);
  146.  
  147. if (! empty($login)) {
  148. // Проверка логина на существование
  149. $checkLogin = User::query()->where('login', $login)->exists();
  150. $validator->false($checkLogin, ['login' => __('users.login_already_exists')]);
  151.  
  152. // Проверка логина в черном списке
  153. $blackLogin = Blacklist::query()
  154. ->where('type', 'login')
  155. ->where('value', strtolower($login))
  156. ->exists();
  157. $validator->false($blackLogin, ['login' => __('users.login_is_blacklisted')]);
  158. }
  159.  
  160. // Проверка email на существование
  161. $checkMail = User::query()->where('email', $email)->exists();
  162. $validator->false($checkMail, ['email' => __('users.email_already_exists')]);
  163.  
  164. // Проверка домена от email в черном списке
  165. $blackDomain = Blacklist::query()
  166. ->where('type', 'domain')
  167. ->where('value', $domain)
  168. ->exists();
  169. $validator->false($blackDomain, ['email' => __('users.domain_is_blacklisted')]);
  170.  
  171. // Проверка email в черном списке
  172. $blackMail = Blacklist::query()
  173. ->where('type', 'email')
  174. ->where('value', $email)
  175. ->exists();
  176. $validator->false($blackMail, ['email' => __('users.email_is_blacklisted')]);
  177.  
  178. // Проверка пригласительного ключа
  179. if (setting('invite')) {
  180. $invitation = Invite::query()
  181. ->select('id')
  182. ->where('hash', $invite)
  183. ->where('used', 0)
  184. ->first();
  185.  
  186. $validator->notEmpty($invitation, ['invite' => __('users.invitation_invalid')]);
  187. }
  188.  
  189. // Регистрация аккаунта
  190. if ($validator->isValid()) {
  191. if (setting('regkeys')) {
  192. $activateKey = Str::random();
  193. $activateLink = config('app.url') . '/key?code=' . $activateKey;
  194. $level = User::PENDED;
  195. }
  196.  
  197. /* @var User $user */
  198. $user = User::query()->create([
  199. 'login' => $login,
  200. 'password' => password_hash($password, PASSWORD_BCRYPT),
  201. 'email' => $email,
  202. 'level' => $level,
  203. 'gender' => $gender,
  204. 'themes' => setting('themes'),
  205. 'point' => 0,
  206. 'language' => setting('language'),
  207. 'money' => setting('registermoney'),
  208. 'confirmregkey' => $activateKey,
  209. 'subscribe' => Str::random(32),
  210. 'updated_at' => SITETIME,
  211. 'created_at' => SITETIME,
  212. ]);
  213.  
  214. // Активация пригласительного ключа
  215. if ($invitation && setting('invite')) {
  216. $invitation->update([
  217. 'used' => 1,
  218. 'invite_user_id' => $user->id,
  219. ]);
  220. }
  221.  
  222. // ----- Уведомление в приват ----//
  223. $textNotice = textNotice('register', ['username' => $login]);
  224. $user->sendMessage(null, $textNotice);
  225.  
  226. // --- Уведомление о регистрации на email ---//
  227. $subject = 'Регистрация на ' . setting('title');
  228. $message = 'Добро пожаловать, ' . $login . '<br>Теперь вы зарегистрированный пользователь сайта <a href="' . config('app.url') . '">' . setting('title') . '</a> , сохраните ваш логин и пароль в надежном месте, они вам еще пригодятся. <br>Ваши данные для входа на сайт <br><b>Логин: ' . $login . '</b><br><b>Пароль: ' . $password . '</b>';
  229.  
  230. $data = [
  231. 'to' => $email,
  232. 'subject' => $subject,
  233. 'text' => $message,
  234. 'activateKey' => $activateKey,
  235. 'activateLink' => $activateLink,
  236. ];
  237.  
  238. sendMail('mailer.register', $data);
  239.  
  240. User::auth($login, $password);
  241.  
  242. setFlash('success', __('users.welcome', ['login' => $login]));
  243.  
  244. return redirect('/');
  245. }
  246.  
  247. setInput($request->all());
  248. setFlash('danger', $validator->getErrors());
  249. }
  250.  
  251. if ($request->has('token')) {
  252. if ($user = User::socialAuth($request->input('token'))) {
  253. setFlash('success', __('users.welcome', ['login' => $user->getName()]));
  254.  
  255. return redirect($request->input('return', '/'));
  256. }
  257. }
  258. }
  259.  
  260. return view('users/register');
  261. }
  262.  
  263. /**
  264. * Login
  265. *
  266. * @param Request $request
  267. * @param Validator $validator
  268. * @param Flood $flood
  269. *
  270. * @return View|RedirectResponse
  271. * @throws GuzzleException
  272. */
  273. public function login(Request $request, Validator $validator, Flood $flood)
  274. {
  275. if (getUser()) {
  276. setFlash('danger', __('main.already_authorized'));
  277.  
  278. return redirect('/');
  279. }
  280.  
  281. $cookieLogin = $request->cookie('login');
  282. $isFlood = $flood->isFlood();
  283.  
  284. if ($request->isMethod('post')) {
  285. if ($request->has(['login', 'password'])) {
  286. if ($isFlood) {
  287. $validator->true(captchaVerify(), ['protect' => __('validator.captcha')]);
  288. }
  289.  
  290. if ($validator->isValid()) {
  291. $login = utfLower($request->input('login'));
  292. $password = $request->input('password');
  293. $remember = $request->boolean('remember');
  294.  
  295. /** @var User $user */
  296. if ($user = User::auth($login, $password, $remember)) {
  297. setFlash('success', __('users.welcome', ['login' => $user->getName()]));
  298.  
  299. return redirect($request->input('return', '/'));
  300. }
  301.  
  302. $flood->saveState(300);
  303. setInput($request->all());
  304. setFlash('danger', __('users.incorrect_login_or_password'));
  305. } else {
  306. setInput($request->all());
  307. setFlash('danger', $validator->getErrors());
  308. }
  309.  
  310. return redirect('login');
  311. }
  312.  
  313. if ($request->has('token')) {
  314. if ($user = User::socialAuth($request->input('token'))) {
  315. setFlash('success', __('users.welcome', ['login' => $user->getName()]));
  316.  
  317. return redirect($request->input('return', '/'));
  318. }
  319. }
  320. }
  321.  
  322. return view('users/login', compact('cookieLogin', 'isFlood'));
  323. }
  324.  
  325. /**
  326. * Exit
  327. *
  328. * @param Request $request
  329. *
  330. * @return RedirectResponse
  331. */
  332. public function logout(Request $request): RedirectResponse
  333. {
  334. if ($request->input('_token') === csrf_token()) {
  335. $request->session()->flush();
  336. cookie()->queue(cookie()->forget('password'));
  337. } else {
  338. setFlash('danger', __('validator.token'));
  339. }
  340.  
  341. return redirect('/');
  342. }
  343.  
  344. /**
  345. * Profile editing
  346. *
  347. * @param Request $request
  348. * @param Validator $validator
  349. *
  350. * @return View|RedirectResponse
  351. */
  352. public function profile(Request $request, Validator $validator)
  353. {
  354. if (! $user = getUser()) {
  355. abort(403, __('main.not_authorized'));
  356. }
  357.  
  358. $fields = UserField::query()
  359. ->select('uf.*', 'ud.value')
  360. ->from('user_fields as uf')
  361. ->leftJoin('user_data as ud', static function (JoinClause $join) use ($user) {
  362. $join->on('uf.id', 'ud.field_id')
  363. ->where('ud.user_id', $user->id);
  364. })
  365. ->orderBy('uf.sort')
  366. ->get();
  367.  
  368. if ($request->isMethod('post')) {
  369. $info = $request->input('info');
  370. $name = $request->input('name');
  371. $country = $request->input('country');
  372. $city = $request->input('city');
  373. $phone = preg_replace('/\D/', '', $request->input('phone') ?? '');
  374. $site = $request->input('site');
  375. $birthday = $request->input('birthday');
  376. $gender = $request->input('gender') === User::MALE ? User::MALE : User::FEMALE;
  377.  
  378. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  379. ->url($site, ['site' => __('validator.site')], false)
  380. ->regex($birthday, '#^[0-9]{2}+\.[0-9]{2}+\.[0-9]{4}$#', ['birthday' => __('validator.date')], false)
  381. ->phone($phone, ['phone' => __('validator.phone')], false)
  382. ->length($info, 0, 1000, ['info' => __('users.info_yourself_long')])
  383. ->length($name, 3, 20, ['name' => __('users.name_short_or_long')], false);
  384.  
  385. foreach ($fields as $field) {
  386. $validator->length(
  387. $request->input('field' . $field->id),
  388. $field->min,
  389. $field->max,
  390. ['field' . $field->id => 'Ошибка'],
  391. $field->required
  392. );
  393. }
  394.  
  395. if ($validator->isValid()) {
  396. $country = utfSubstr($country, 0, 30);
  397. $city = utfSubstr($city, 0, 50);
  398.  
  399. $user->update([
  400. 'name' => $name,
  401. 'gender' => $gender,
  402. 'country' => $country,
  403. 'city' => $city,
  404. 'phone' => $phone,
  405. 'site' => $site,
  406. 'birthday' => $birthday,
  407. 'info' => $info,
  408. ]);
  409.  
  410. foreach ($fields as $field) {
  411. $user->data()
  412. ->updateOrCreate([
  413. 'field_id' => $field->id,
  414. ], [
  415. 'value' => $request->input('field' . $field->id),
  416. ]);
  417. }
  418.  
  419. setFlash('success', __('users.profile_success_changed'));
  420.  
  421. return redirect('profile');
  422. }
  423.  
  424. setInput($request->all());
  425. setFlash('danger', $validator->getErrors());
  426. }
  427.  
  428. return view('users/profile', compact('user', 'fields'));
  429. }
  430.  
  431. /**
  432. * Confirmation of registration
  433. *
  434. * @param Request $request
  435. * @param Validator $validator
  436. *
  437. * @return View|RedirectResponse
  438. */
  439. public function key(Request $request, Validator $validator)
  440. {
  441. /* @var User $user */
  442. if (! $user = getUser()) {
  443. abort(403, __('main.not_authorized'));
  444. }
  445.  
  446. if (! setting('regkeys')) {
  447. abort(200, __('users.confirm_registration_disabled'));
  448. }
  449.  
  450. if ($user->level !== User::PENDED) {
  451. abort(403, __('users.profile_not_confirmation'));
  452. }
  453.  
  454. /* Повторная отправка */
  455. if ($request->has('email') && $request->isMethod('post')) {
  456. $email = strtolower($request->input('email'));
  457. $domain = utfSubstr(strrchr($email, '@'), 1);
  458.  
  459. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  460. ->true(captchaVerify(), ['protect' => __('validator.captcha')])
  461. ->email($email, ['email' => __('validator.email')]);
  462.  
  463. $regMail = User::query()->where('login', '<>', $user->login)->where('email', $email)->count();
  464. $validator->empty($regMail, ['email' => __('users.email_already_exists')]);
  465.  
  466. $blackMail = BlackList::query()->where('type', 'email')->where('value', $email)->count();
  467. $validator->empty($blackMail, ['email' => __('users.email_is_blacklisted')]);
  468.  
  469. $blackDomain = Blacklist::query()->where('type', 'domain')->where('value', $domain)->count();
  470. $validator->empty($blackDomain, ['email' => __('users.domain_is_blacklisted')]);
  471.  
  472. if ($validator->isValid()) {
  473. $activateKey = Str::random();
  474. $activateLink = config('app.url') . '/key?code=' . $activateKey;
  475.  
  476. $user->update([
  477. 'email' => $email,
  478. 'confirmregkey' => $activateKey,
  479. ]);
  480.  
  481. /* Уведомление о регистрации на email */
  482. $subject = 'Регистрация на ' . setting('title');
  483. $message = 'Добро пожаловать, ' . e($user->getName()) . '<br>Теперь вы зарегистрированный пользователь сайта <a href="' . config('app.url') . '">' . setting('title') . '</a> , сохраните ваш логин и пароль в надежном месте, они вам еще пригодятся.';
  484.  
  485. $data = [
  486. 'to' => $email,
  487. 'subject' => $subject,
  488. 'text' => $message,
  489. 'activateKey' => $activateKey,
  490. 'activateLink' => $activateLink,
  491. ];
  492.  
  493. sendMail('mailer.register', $data);
  494. setFlash('success', __('users.confirm_code_success_sent'));
  495.  
  496. return redirect('/');
  497. }
  498.  
  499. setInput($request->all());
  500. setFlash('danger', $validator->getErrors());
  501. }
  502.  
  503. /* Подтверждение кода */
  504. if ($request->has('code')) {
  505. $code = $request->input('code');
  506.  
  507. if ($code === $user->confirmregkey) {
  508. $user->update([
  509. 'confirmregkey' => null,
  510. 'level' => User::USER,
  511. ]);
  512.  
  513. setFlash('success', __('users.account_success_activated'));
  514.  
  515. return redirect('/');
  516. }
  517.  
  518. setFlash('danger', __('users.confirm_code_invalid'));
  519. }
  520.  
  521. return view('users/key', compact('user'));
  522. }
  523.  
  524. /**
  525. * Settings
  526. *
  527. * @param Request $request
  528. * @param Validator $validator
  529. *
  530. * @return View|RedirectResponse
  531. */
  532. public function setting(Request $request, Validator $validator)
  533. {
  534. if (! $user = getUser()) {
  535. abort(403, __('main.not_authorized'));
  536. }
  537.  
  538. $setting['themes'] = array_map('basename', glob(public_path('/themes/*'), GLOB_ONLYDIR));
  539. $setting['languages'] = array_map('basename', glob(resource_path('lang/*'), GLOB_ONLYDIR));
  540. $setting['timezones'] = range(-12, 12);
  541.  
  542. if ($request->isMethod('post')) {
  543. $themes = $request->input('themes');
  544. $timezone = $request->input('timezone', 0);
  545. $language = $request->input('language');
  546. $notify = $request->input('notify') ? 1 : 0;
  547. $subscribe = $request->input('subscribe') ? Str::random(32) : null;
  548.  
  549. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  550. ->regex($themes, '|^[a-z0-9_\-]+$|i', ['themes' => __('users.theme_invalid')])
  551. ->true(in_array($themes, $setting['themes'], true) || empty($themes), ['themes' => __('users.theme_not_installed')])
  552. ->regex($language, '|^[a-z]+$|', ['language' => __('users.language_invalid')])
  553. ->in($language, $setting['languages'], ['language' => __('users.language_not_installed')])
  554. ->regex($timezone, '|^[\-\+]{0,1}[0-9]{1,2}$|', ['timezone' => __('users.timezone_invalid')]);
  555.  
  556. if ($validator->isValid()) {
  557. $user->update([
  558. 'themes' => $themes,
  559. 'timezone' => $timezone,
  560. 'notify' => $notify,
  561. 'subscribe' => $subscribe,
  562. 'language' => $language,
  563. ]);
  564.  
  565. setFlash('success', __('users.settings_success_changed'));
  566.  
  567. return redirect('settings');
  568. }
  569.  
  570. setInput($request->all());
  571. setFlash('danger', $validator->getErrors());
  572. }
  573.  
  574. return view('users/settings', compact('user', 'setting'));
  575. }
  576.  
  577. /**
  578. * User data
  579. *
  580. * @return View
  581. */
  582. public function account(): View
  583. {
  584. if (! $user = getUser()) {
  585. abort(403, __('main.not_authorized'));
  586. }
  587.  
  588. return view('users/account', compact('user'));
  589. }
  590.  
  591. /**
  592. * Initialize email change
  593. *
  594. * @param Request $request
  595. * @param Validator $validator
  596. *
  597. * @return RedirectResponse
  598. */
  599. public function changeMail(Request $request, Validator $validator): RedirectResponse
  600. {
  601. if (! $user = getUser()) {
  602. abort(403, __('main.not_authorized'));
  603. }
  604.  
  605. $email = strtolower($request->input('email'));
  606. $password = $request->input('password');
  607.  
  608. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  609. ->notEqual($email, $user->email, ['email' => __('users.email_different')])
  610. ->email($email, ['email' => __('validator.email')])
  611. ->true(password_verify($password, $user->password), ['password' => __('users.password_different')]);
  612.  
  613. $regMail = User::query()->where('email', $email)->first();
  614. $validator->empty($regMail, ['email' => __('users.email_already_exists')]);
  615.  
  616. // Проверка email в черном списке
  617. $blackMail = BlackList::query()->where('type', 'email')->where('value', $email)->first();
  618. $validator->empty($blackMail, ['email' => __('users.email_is_blacklisted')]);
  619.  
  620. ChangeMail::query()->where('created_at', '<', SITETIME)->delete();
  621.  
  622. $changeMail = ChangeMail::query()->where('user_id', $user->id)->first();
  623. $validator->empty($changeMail, __('users.confirm_already_sent'));
  624.  
  625. if ($validator->isValid()) {
  626. $genkey = Str::random();
  627.  
  628. $subject = 'Изменение email на ' . setting('title');
  629. $message = 'Здравствуйте, ' . e($user->getName()) . '<br>Вами была произведена операция по изменению адреса электронной почты<br><br>Для того, чтобы изменить email, необходимо подтвердить новый адрес почты<br>Перейдите по данной ссылке:<br><br><a href="' . config('app.url') . '/accounts/editmail?key=' . $genkey . '">' . config('app.url') . '/accounts/editmail?key=' . $genkey . '</a><br><br>Ссылка будет дейстительной в течение суток до ' . date('j.m.y / H:i', strtotime('+1 day', SITETIME)) . '<br>Для изменения адреса необходимо быть авторизованным на сайте<br>Если это сообщение попало к вам по ошибке или вы не собираетесь менять email, то просто проигнорируйте данное письмо';
  630.  
  631. $data = [
  632. 'to' => $email,
  633. 'subject' => $subject,
  634. 'text' => $message,
  635. ];
  636.  
  637. sendMail('mailer.default', $data);
  638.  
  639. changeMail::query()->create([
  640. 'user_id' => $user->id,
  641. 'mail' => $email,
  642. 'hash' => $genkey,
  643. 'created_at' => strtotime('+1 hour', SITETIME),
  644. ]);
  645.  
  646. setFlash('success', __('users.confirm_success_sent'));
  647. } else {
  648. setInput($request->all());
  649. setFlash('danger', $validator->getErrors());
  650. }
  651.  
  652. return redirect('accounts');
  653. }
  654.  
  655. /**
  656. * Email change
  657. *
  658. * @param Request $request
  659. * @param Validator $validator
  660. *
  661. * @return RedirectResponse
  662. * @throws Exception
  663. */
  664. public function editMail(Request $request, Validator $validator): RedirectResponse
  665. {
  666. if (! $user = getUser()) {
  667. abort(403, __('main.not_authorized'));
  668. }
  669.  
  670. $key = $request->input('key');
  671.  
  672. ChangeMail::query()->where('created_at', '<', SITETIME)->delete();
  673.  
  674. /** @var ChangeMail $changeMail */
  675. $changeMail = ChangeMail::query()->where('hash', $key)->where('user_id', $user->id)->first();
  676.  
  677. $validator->notEmpty($key, __('users.changed_code_empty'))
  678. ->notEmpty($changeMail, __('users.changed_code_not_found'));
  679.  
  680. if ($changeMail) {
  681. $validator->notEqual($changeMail->mail, $user->mail, __('users.email_different'));
  682.  
  683. $regMail = User::query()->where('email', $changeMail->mail)->count();
  684. $validator->empty($regMail, __('users.email_already_exists'));
  685.  
  686. $blackMail = BlackList::query()->where('type', 'email')->where('value', $changeMail->mail)->count();
  687. $validator->empty($blackMail, __('users.email_is_blacklisted'));
  688. }
  689.  
  690. if ($validator->isValid()) {
  691. $user->update([
  692. 'email' => $changeMail->mail,
  693. ]);
  694.  
  695. $changeMail->delete();
  696.  
  697. setFlash('success', __('users.email_success_changed'));
  698. } else {
  699. setFlash('danger', $validator->getErrors());
  700. }
  701.  
  702. return redirect('accounts');
  703. }
  704.  
  705. /**
  706. * Status change
  707. *
  708. * @param Request $request
  709. * @param Validator $validator
  710. *
  711. * @return RedirectResponse
  712. */
  713. public function editStatus(Request $request, Validator $validator): RedirectResponse
  714. {
  715. if (! $user = getUser()) {
  716. abort(403, __('main.not_authorized'));
  717. }
  718.  
  719. $status = $request->input('status');
  720. $status = ! empty($status) ? $status : null;
  721. $cost = $status ? setting('editstatusmoney') : 0;
  722.  
  723. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  724. ->empty($user->ban, ['status' => __('users.status_changed_not_ban')])
  725. ->notEqual($status, $user->status, ['status' => __('users.status_different')])
  726. ->gte($user->point, setting('editstatuspoint'), ['status' => __('users.status_points')])
  727. ->gte($user->money, $cost, ['status' => __('users.status_moneys')])
  728. ->length($status, 3, 20, ['status' => __('users.status_short_or_long')], false);
  729.  
  730. if ($validator->isValid()) {
  731. $user->update([
  732. 'status' => $status,
  733. 'money' => DB::raw('money - ' . $cost),
  734. ]);
  735.  
  736. clearCache('status');
  737. setFlash('success', __('users.status_success_changed'));
  738. } else {
  739. setInput($request->all());
  740. setFlash('danger', $validator->getErrors());
  741. }
  742.  
  743. return redirect('accounts');
  744. }
  745.  
  746. /**
  747. * Color change
  748. *
  749. * @param Request $request
  750. * @param Validator $validator
  751. *
  752. * @return RedirectResponse
  753. */
  754. public function editColor(Request $request, Validator $validator): RedirectResponse
  755. {
  756. if (! $user = getUser()) {
  757. abort(403, __('main.not_authorized'));
  758. }
  759.  
  760. $color = $request->input('color');
  761. $color = ! empty($color) ? $color : null;
  762. $cost = $color ? setting('editcolormoney') : 0;
  763.  
  764. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  765. ->notEqual($color, $user->color, ['color' => __('users.color_different')])
  766. ->gte($user->point, setting('editcolorpoint'), ['color' => __('users.color_points')])
  767. ->gte($user->money, $cost, ['color' => __('users.color_moneys')])
  768. ->regex($color, '|^#+[A-f0-9]{6}$|', ['color' => __('validator.color')], false);
  769.  
  770. if ($validator->isValid()) {
  771. $user->update([
  772. 'color' => $color,
  773. 'money' => DB::raw('money - ' . $cost),
  774. ]);
  775.  
  776. setFlash('success', __('users.color_success_changed'));
  777. } else {
  778. setInput($request->all());
  779. setFlash('danger', $validator->getErrors());
  780. }
  781.  
  782. return redirect('accounts');
  783. }
  784.  
  785. /**
  786. * Password change
  787. *
  788. * @param Request $request
  789. * @param Validator $validator
  790. *
  791. * @return RedirectResponse
  792. */
  793. public function editPassword(Request $request, Validator $validator): RedirectResponse
  794. {
  795. if (! $user = getUser()) {
  796. abort(403, __('main.not_authorized'));
  797. }
  798.  
  799. $newpass = $request->input('newpass');
  800. $newpass2 = $request->input('newpass2');
  801. $oldpass = $request->input('oldpass');
  802.  
  803. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  804. ->true(password_verify($oldpass, $user->password), ['oldpass' => __('users.password_different')])
  805. ->length($newpass, 6, 20, ['newpass' => __('users.password_length_requirements')])
  806. ->notEqual($user->login, $newpass, ['newpass' => __('users.login_different')])
  807. ->equal($newpass, $newpass2, ['newpass2' => __('users.passwords_different')]);
  808.  
  809. if (ctype_digit($newpass)) {
  810. $validator->addError(['newpass' => __('users.field_characters_requirements')]);
  811. }
  812.  
  813. if ($validator->isValid()) {
  814. $user->update([
  815. 'password' => password_hash($newpass, PASSWORD_BCRYPT),
  816. ]);
  817.  
  818. $subject = 'Изменение пароля на ' . setting('title');
  819. $message = 'Здравствуйте, ' . e($user->getName()) . '<br>Вами была произведена операция по изменению пароля<br><br><b>Ваш новый пароль: ' . $newpass . '</b><br>Сохраните его в надежном месте<br><br>Данные инициализации:<br>IP: ' . getIp() . '<br>Браузер: ' . getBrowser() . '<br>Время: ' . date('j.m.y / H:i', SITETIME);
  820.  
  821. $data = [
  822. 'to' => $user->email,
  823. 'subject' => $subject,
  824. 'text' => $message,
  825. ];
  826.  
  827. sendMail('mailer.default', $data);
  828.  
  829. $request->session()->forget(['id', 'password']);
  830.  
  831. setFlash('success', __('users.password_success_changed'));
  832.  
  833. return redirect('login');
  834. }
  835.  
  836. setInput($request->all());
  837. setFlash('danger', $validator->getErrors());
  838.  
  839. return redirect('accounts');
  840. }
  841.  
  842. /**
  843. * Key generation
  844. *
  845. * @param Request $request
  846. *
  847. * @return RedirectResponse
  848. */
  849. public function apikey(Request $request): RedirectResponse
  850. {
  851. if (! $user = getUser()) {
  852. abort(403, __('main.not_authorized'));
  853. }
  854.  
  855. if ($request->input('_token') === csrf_token()) {
  856. $apiKey = md5($user->login . Str::random());
  857. $message = __('users.token_success_changed');
  858.  
  859. if ($request->input('action') === 'create') {
  860. $message = __('users.token_success_created');
  861. }
  862.  
  863. if ($request->input('action') === 'delete') {
  864. $apiKey = '';
  865. $message = __('users.token_success_deleted');
  866. }
  867.  
  868. $user->update([
  869. 'apikey' => $apiKey
  870. ]);
  871.  
  872. setFlash('success', $message);
  873. } else {
  874. setFlash('danger', __('validator.token'));
  875. }
  876.  
  877. return redirect('accounts');
  878. }
  879.  
  880. /**
  881. * Проверка доступности логина
  882. *
  883. * @param Request $request
  884. * @param Validator $validator
  885. *
  886. * @return JsonResponse
  887. * @throws Exception
  888. */
  889. public function checkLogin(Request $request, Validator $validator): JsonResponse
  890. {
  891. $login = (string) $request->input('login');
  892.  
  893. $validator
  894. ->true($request->ajax(), __('validator.not_ajax'))
  895. ->regex($login, '|^[a-z0-9\-]+$|i', __('validator.login'))
  896. ->regex(utfSubstr($login, 0, 1), '|^[a-z0-9]+$|i', __('users.login_begin_requirements'))
  897. ->length($login, 3, 20, __('users.login_length_requirements'))
  898. ->false(ctype_digit($login), __('users.field_characters_requirements'))
  899. ->false(substr_count($login, '-') > 2, __('users.login_hyphens_requirements'));
  900.  
  901. if ($validator->isValid()) {
  902. $existLogin = User::query()
  903. ->where('login', $login)
  904. ->exists();
  905.  
  906. $blackLogin = Blacklist::query()
  907. ->where('type', 'login')
  908. ->where('value', strtolower($login))
  909. ->exists();
  910.  
  911. $validator
  912. ->false($existLogin, __('users.login_already_exists'))
  913. ->false($blackLogin, __('users.login_is_blacklisted'));
  914. }
  915.  
  916. if ($validator->isValid()) {
  917. return response()->json(['success' => true]);
  918. }
  919.  
  920. return response()->json([
  921. 'success' => false,
  922. 'message' => current($validator->getErrors()),
  923. ]);
  924. }
  925. }