Organized password reset and account activation
This commit is contained in:
parent
83239a492d
commit
893e841a87
3 changed files with 91 additions and 83 deletions
|
@ -149,6 +149,13 @@ $userValidation =
|
||||||
\Chibi\Router::register(['UserController', 'registrationView'], 'GET', '/register', $userValidation);
|
\Chibi\Router::register(['UserController', 'registrationView'], 'GET', '/register', $userValidation);
|
||||||
\Chibi\Router::register(['UserController', 'registrationAction'], 'POST', '/register', $userValidation);
|
\Chibi\Router::register(['UserController', 'registrationAction'], 'POST', '/register', $userValidation);
|
||||||
|
|
||||||
|
\Chibi\Router::register(['UserController', 'activationView'], 'GET', '/activation', $userValidation);
|
||||||
|
\Chibi\Router::register(['UserController', 'activationAction'], 'POST', '/activation', $userValidation);
|
||||||
|
\Chibi\Router::register(['UserController', 'activationAction'], 'GET', '/activation/{token}', $userValidation);
|
||||||
|
\Chibi\Router::register(['UserController', 'passwordResetView'], 'GET', '/password-reset', $userValidation);
|
||||||
|
\Chibi\Router::register(['UserController', 'passwordResetAction'], 'POST', '/password-reset', $userValidation);
|
||||||
|
\Chibi\Router::register(['UserController', 'passwordResetAction'], 'GET', '/password-reset/{token}', $userValidation);
|
||||||
|
|
||||||
\Chibi\Router::register(['UserController', 'flagAction'], 'POST', '/user/{name}/flag', $userValidation);
|
\Chibi\Router::register(['UserController', 'flagAction'], 'POST', '/user/{name}/flag', $userValidation);
|
||||||
\Chibi\Router::register(['UserController', 'banAction'], 'POST', '/user/{name}/ban', $userValidation);
|
\Chibi\Router::register(['UserController', 'banAction'], 'POST', '/user/{name}/ban', $userValidation);
|
||||||
\Chibi\Router::register(['UserController', 'unbanAction'], 'POST', '/user/{name}/unban', $userValidation);
|
\Chibi\Router::register(['UserController', 'unbanAction'], 'POST', '/user/{name}/unban', $userValidation);
|
||||||
|
@ -161,12 +168,6 @@ foreach (['GET', 'POST'] as $method)
|
||||||
{
|
{
|
||||||
\Chibi\Router::register(['TagController', 'massTagRedirectAction'], $method, '/mass-tag-redirect', $tagValidation);
|
\Chibi\Router::register(['TagController', 'massTagRedirectAction'], $method, '/mass-tag-redirect', $tagValidation);
|
||||||
|
|
||||||
\Chibi\Router::register(['UserController', 'activationAction'], $method, '/activation/{token}', $userValidation);
|
|
||||||
\Chibi\Router::register(['UserController', 'activationProxyAction'], $method, '/activation-proxy', $userValidation);
|
|
||||||
\Chibi\Router::register(['UserController', 'activationProxyAction'], $method, '/activation-proxy/{token}', $userValidation);
|
|
||||||
\Chibi\Router::register(['UserController', 'passwordResetAction'], $method, '/password-reset/{token}', $userValidation);
|
|
||||||
\Chibi\Router::register(['UserController', 'passwordResetProxyAction'], $method, '/password-reset-proxy', $userValidation);
|
|
||||||
\Chibi\Router::register(['UserController', 'passwordResetProxyAction'], $method, '/password-reset-proxy/{token}', $userValidation);
|
|
||||||
\Chibi\Router::register(['UserController', 'toggleSafetyAction'], $method, '/user/toggle-safety/{safety}', $userValidation);
|
\Chibi\Router::register(['UserController', 'toggleSafetyAction'], $method, '/user/toggle-safety/{safety}', $userValidation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -216,32 +216,66 @@ class UserController
|
||||||
Messenger::message($message);
|
Messenger::message($message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function activationView()
|
||||||
|
{
|
||||||
|
$context = getContext();
|
||||||
|
$context->viewName = 'user-select';
|
||||||
|
Assets::setSubTitle('account activation');
|
||||||
|
}
|
||||||
|
|
||||||
public function activationAction($token)
|
public function activationAction($token)
|
||||||
{
|
{
|
||||||
$context = getContext();
|
$context = getContext();
|
||||||
$context->viewName = 'message';
|
$context->viewName = 'message';
|
||||||
Assets::setSubTitle('account activation');
|
Assets::setSubTitle('account activation');
|
||||||
|
|
||||||
$dbToken = TokenModel::findByToken($token);
|
if (empty($token))
|
||||||
TokenModel::checkValidity($dbToken);
|
|
||||||
|
|
||||||
$dbUser = $dbToken->getUser();
|
|
||||||
$dbUser->emailConfirmed = $dbUser->emailUnconfirmed;
|
|
||||||
$dbUser->emailUnconfirmed = null;
|
|
||||||
$dbToken->used = true;
|
|
||||||
TokenModel::save($dbToken);
|
|
||||||
UserModel::save($dbUser);
|
|
||||||
|
|
||||||
LogHelper::log('{subject} just activated account', ['subject' => TextHelper::reprUser($dbUser)]);
|
|
||||||
$message = 'Activation completed successfully.';
|
|
||||||
if (getConfig()->registration->staffActivation)
|
|
||||||
$message .= ' However, your account still must be confirmed by staff.';
|
|
||||||
Messenger::message($message);
|
|
||||||
|
|
||||||
if (!getConfig()->registration->staffActivation)
|
|
||||||
{
|
{
|
||||||
Auth::setCurrentUser($dbUser);
|
$name = InputHelper::get('name');
|
||||||
|
$user = UserModel::findByNameOrEmail($name);
|
||||||
|
if (empty($user->emailUnconfirmed))
|
||||||
|
{
|
||||||
|
if (!empty($user->emailConfirmed))
|
||||||
|
throw new SimpleException('E-mail was already confirmed; activation skipped');
|
||||||
|
else
|
||||||
|
throw new SimpleException('This user has no e-mail specified; activation cannot proceed');
|
||||||
|
}
|
||||||
|
EditUserEmailJob::sendEmail($user);
|
||||||
|
Messenger::message('Activation e-mail resent.');
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$dbToken = TokenModel::findByToken($token);
|
||||||
|
TokenModel::checkValidity($dbToken);
|
||||||
|
|
||||||
|
$dbUser = $dbToken->getUser();
|
||||||
|
if (empty($dbUser->emailConfirmed))
|
||||||
|
{
|
||||||
|
$dbUser->emailConfirmed = $dbUser->emailUnconfirmed;
|
||||||
|
$dbUser->emailUnconfirmed = null;
|
||||||
|
}
|
||||||
|
$dbToken->used = true;
|
||||||
|
TokenModel::save($dbToken);
|
||||||
|
UserModel::save($dbUser);
|
||||||
|
|
||||||
|
LogHelper::log('{subject} just activated account', ['subject' => TextHelper::reprUser($dbUser)]);
|
||||||
|
$message = 'Activation completed successfully.';
|
||||||
|
if (getConfig()->registration->staffActivation)
|
||||||
|
$message .= ' However, your account still must be confirmed by staff.';
|
||||||
|
Messenger::message($message);
|
||||||
|
|
||||||
|
if (!getConfig()->registration->staffActivation)
|
||||||
|
{
|
||||||
|
Auth::setCurrentUser($dbUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function passwordResetView()
|
||||||
|
{
|
||||||
|
$context = getContext();
|
||||||
|
$context->viewName = 'user-select';
|
||||||
|
Assets::setSubTitle('password reset');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function passwordResetAction($token)
|
public function passwordResetAction($token)
|
||||||
|
@ -250,66 +284,39 @@ class UserController
|
||||||
$context->viewName = 'message';
|
$context->viewName = 'message';
|
||||||
Assets::setSubTitle('password reset');
|
Assets::setSubTitle('password reset');
|
||||||
|
|
||||||
$dbToken = TokenModel::findByToken($token);
|
if (empty($token))
|
||||||
TokenModel::checkValidity($dbToken);
|
|
||||||
|
|
||||||
$alphabet = array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9'));
|
|
||||||
$randomPassword = join('', array_map(function($x) use ($alphabet)
|
|
||||||
{
|
{
|
||||||
return $alphabet[$x];
|
$name = InputHelper::get('name');
|
||||||
}, array_rand($alphabet, 8)));
|
$user = UserModel::findByNameOrEmail($name);
|
||||||
|
if (empty($user->emailConfirmed))
|
||||||
|
throw new SimpleException('This user has no e-mail confirmed; password reset cannot proceed');
|
||||||
|
|
||||||
$dbUser = $dbToken->getUser();
|
self::sendPasswordResetConfirmation($user);
|
||||||
$dbUser->passHash = UserModel::hashPassword($randomPassword, $dbUser->passSalt);
|
Messenger::message('E-mail sent. Follow instructions to reset password.');
|
||||||
$dbToken->used = true;
|
}
|
||||||
TokenModel::save($dbToken);
|
else
|
||||||
UserModel::save($dbUser);
|
{
|
||||||
|
$dbToken = TokenModel::findByToken($token);
|
||||||
LogHelper::log('{subject} just reset password', ['subject' => TextHelper::reprUser($dbUser)]);
|
TokenModel::checkValidity($dbToken);
|
||||||
$message = 'Password reset successful. Your new password is **' . $randomPassword . '**.';
|
|
||||||
Messenger::message($message);
|
$alphabet = array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9'));
|
||||||
|
$randomPassword = join('', array_map(function($x) use ($alphabet)
|
||||||
Auth::setCurrentUser($dbUser);
|
{
|
||||||
}
|
return $alphabet[$x];
|
||||||
|
}, array_rand($alphabet, 8)));
|
||||||
public function passwordResetProxyAction()
|
|
||||||
{
|
$dbUser = $dbToken->getUser();
|
||||||
$context = getContext();
|
$dbUser->passHash = UserModel::hashPassword($randomPassword, $dbUser->passSalt);
|
||||||
$context->viewName = 'user-select';
|
$dbToken->used = true;
|
||||||
Assets::setSubTitle('password reset');
|
TokenModel::save($dbToken);
|
||||||
|
UserModel::save($dbUser);
|
||||||
if (!InputHelper::get('submit'))
|
|
||||||
return;
|
LogHelper::log('{subject} just reset password', ['subject' => TextHelper::reprUser($dbUser)]);
|
||||||
|
$message = 'Password reset successful. Your new password is **' . $randomPassword . '**.';
|
||||||
$name = InputHelper::get('name');
|
Messenger::message($message);
|
||||||
$user = UserModel::findByNameOrEmail($name);
|
|
||||||
if (empty($user->emailConfirmed))
|
Auth::setCurrentUser($dbUser);
|
||||||
throw new SimpleException('This user has no e-mail confirmed; password reset cannot proceed');
|
|
||||||
|
|
||||||
self::sendPasswordResetConfirmation($user);
|
|
||||||
Messenger::message('E-mail sent. Follow instructions to reset password.');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function activationProxyAction()
|
|
||||||
{
|
|
||||||
$context = getContext();
|
|
||||||
$context->viewName = 'user-select';
|
|
||||||
Assets::setSubTitle('account activation');
|
|
||||||
|
|
||||||
if (!InputHelper::get('submit'))
|
|
||||||
return;
|
|
||||||
|
|
||||||
$name = InputHelper::get('name');
|
|
||||||
$user = UserModel::findByNameOrEmail($name);
|
|
||||||
if (empty($user->emailUnconfirmed))
|
|
||||||
{
|
|
||||||
if (!empty($user->emailConfirmed))
|
|
||||||
throw new SimpleException('E-mail was already confirmed; activation skipped');
|
|
||||||
else
|
|
||||||
throw new SimpleException('This user has no e-mail specified; activation cannot proceed');
|
|
||||||
}
|
}
|
||||||
EditUserEmailJob::sendEmail($user);
|
|
||||||
Messenger::message('Activation e-mail resent.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function sendPasswordResetConfirmation($user)
|
private static function sendPasswordResetConfirmation($user)
|
||||||
|
|
|
@ -43,8 +43,8 @@ Assets::addStylesheet('auth.css');
|
||||||
<div>
|
<div>
|
||||||
<p>Problems logging in?</p>
|
<p>Problems logging in?</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="<?= \Chibi\Router::linkTo(['UserController', 'passwordResetProxyAction']) ?>">I don't remember my password</a></li>
|
<li><a href="<?= \Chibi\Router::linkTo(['UserController', 'passwordResetView']) ?>">I don't remember my password</a></li>
|
||||||
<li><a href="<?= \Chibi\Router::linkTo(['UserController', 'activationProxyAction']) ?>">I haven't received activation e-mail</a></li>
|
<li><a href="<?= \Chibi\Router::linkTo(['UserController', 'activationView']) ?>">I haven't received activation e-mail</a></li>
|
||||||
<li><a href="<?= \Chibi\Router::linkTo(['UserController', 'registrationView']) ?>">I don't have an account</a></li>
|
<li><a href="<?= \Chibi\Router::linkTo(['UserController', 'registrationView']) ?>">I don't have an account</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue