0, 'name' => '', 'avatar' => url('user-avatar', ['res' => 200, 'user' => 0]), ]); return; } echo json_encode([ 'id' => $userInfo->getId(), 'name' => $userInfo->getUsername(), 'avatar' => url('user-avatar', ['user' => $userInfo->getId(), 'res' => 200]), ]); return; } $notices = []; $ipAddress = $_SERVER['REMOTE_ADDR']; $countryCode = $_SERVER['COUNTRY_CODE'] ?? 'XX'; $remainingAttempts = UserLoginAttempt::remaining($ipAddress); $siteIsPrivate = $cfg->getBoolean('private.enable'); if($siteIsPrivate) { [ 'private.perm.cat' => $loginPermCat, 'private.perm.val' => $loginPermVal, 'private.msg' => $sitePrivateMessage, 'private.allow_password_reset' => $canResetPassword, ] = $cfg->getValues([ 'private.perm.cat:s', 'private.perm.val:i', 'private.msg:s', ['private.allow_password_reset:b', true], ]); } else { $loginPermCat = ''; $loginPermVal = 0; $sitePrivateMessage = ''; $canResetPassword = true; } while(!empty($_POST['login']) && is_array($_POST['login'])) { if(!CSRF::validateRequest()) { $notices[] = 'Was unable to verify the request, please try again!'; break; } $loginRedirect = empty($_POST['login']['redirect']) || !is_string($_POST['login']['redirect']) ? '' : $_POST['login']['redirect']; if(empty($_POST['login']['username']) || empty($_POST['login']['password']) || !is_string($_POST['login']['username']) || !is_string($_POST['login']['password'])) { $notices[] = "You didn't fill in a username and/or password."; break; } if($remainingAttempts < 1) { $notices[] = "There are too many failed login attempts from your IP address, please try again later."; break; } $attemptsRemainingError = sprintf( "%d attempt%s remaining", $remainingAttempts - 1, $remainingAttempts === 2 ? '' : 's' ); $loginFailedError = "Invalid username or password, {$attemptsRemainingError}."; try { $userInfo = User::byUsernameOrEMailAddress($_POST['login']['username']); } catch(RuntimeException $ex) { UserLoginAttempt::create($ipAddress, $countryCode, false); $notices[] = $loginFailedError; break; } if(!$userInfo->hasPassword()) { $notices[] = 'Your password has been invalidated, please reset it.'; break; } if($userInfo->isDeleted() || !$userInfo->checkPassword($_POST['login']['password'])) { UserLoginAttempt::create($ipAddress, $countryCode, false, $userInfo); $notices[] = $loginFailedError; break; } if($userInfo->passwordNeedsRehash()) $userInfo->setPassword($_POST['login']['password'])->save(); if(!empty($loginPermCat) && $loginPermVal > 0 && !perms_check_user($loginPermCat, $userInfo->getId(), $loginPermVal)) { $notices[] = "Login succeeded, but you're not allowed to browse the site right now."; UserLoginAttempt::create($ipAddress, $countryCode, true, $userInfo); break; } if($userInfo->hasTOTP()) { url_redirect('auth-two-factor', [ 'token' => UserAuthSession::create($userInfo)->getToken(), ]); return; } UserLoginAttempt::create($ipAddress, $countryCode, true, $userInfo); try { $sessionInfo = UserSession::create($userInfo, $ipAddress, $countryCode); $sessionInfo->setCurrent(); } catch(RuntimeException $ex) { $notices[] = "Something broke while creating a session for you, please tell an administrator or developer about this!"; break; } $authToken = AuthToken::create($userInfo, $sessionInfo); $authToken->applyCookie($sessionInfo->getExpiresTime()); if(!is_local_url($loginRedirect)) $loginRedirect = url('index'); redirect($loginRedirect); return; } $welcomeMode = !empty($_GET['welcome']); $loginUsername = !empty($_POST['login']['username']) && is_string($_POST['login']['username']) ? $_POST['login']['username'] : ( !empty($_GET['username']) && is_string($_GET['username']) ? $_GET['username'] : '' ); $loginRedirect = $welcomeMode ? url('index') : (!empty($_GET['redirect']) && is_string($_GET['redirect']) ? $_GET['redirect'] : null) ?? $_SERVER['HTTP_REFERER'] ?? url('index'); $canRegisterAccount = !$siteIsPrivate; Template::render('auth.login', [ 'login_notices' => $notices, 'login_username' => $loginUsername, 'login_redirect' => $loginRedirect, 'login_can_reset_password' => $canResetPassword, 'login_can_register' => $canRegisterAccount, 'login_attempts_remaining' => $remainingAttempts, 'login_welcome' => $welcomeMode, 'login_private' => [ 'enabled' => $siteIsPrivate, 'message' => $sitePrivateMessage, ], ]);