This commit is contained in:
Marcin Kurczewski 2013-11-16 19:24:33 +01:00
parent 039d56c260
commit bb01ae7fca
4 changed files with 119 additions and 21 deletions

View file

@ -41,15 +41,25 @@ needEmailForRegistering = 1
needEmailForCommenting = 0 needEmailForCommenting = 0
needEmailForUploading = 1 needEmailForUploading = 1
confirmationEmailEnabled = 1 confirmationEmailEnabled = 1
confirmationEmailSenderName = "{host} registration engine" confirmationEmailSenderName = "{host} mailing system"
confirmationEmailSenderEmail = "noreply@{host}" confirmationEmailSenderEmail = "noreply@{host}"
confirmationEmailSubject = "{host} activation" confirmationEmailSubject = "{host} - account activation"
confirmationEmailBody = "Hello, confirmationEmailBody = "Hello,
You received this e-mail because someone registered a user with this address at {host}. If it's you, visit {link} to finish registration process, otherwise you may ignore and delete this e-mail. You received this e-mail because someone registered a user with this e-mail address at {host}. If it's you, visit {link} to finish registration process, otherwise you may ignore and delete this e-mail.
Kind regards, Kind regards,
{host} registration engine" {host} mailing system"
passwordResetEmailSenderName = "{host} mailing system"
passwordResetEmailSenderEmail = "noreply@{host}"
passwordResetEmailSubject = "{host} - password reset"
passwordResetEmailBody = "Hello,
You received this e-mail because someone requested a password reset for user with this e-mail address at {host}. If it's you, visit {link} to finish password reset process, otherwise you may ignore and delete this e-mail.
Kind regards,
{host} mailing system"
[privileges] [privileges]
uploadPost=registered uploadPost=registered

View file

@ -32,6 +32,9 @@ class UserController
$senderName = TextHelper::replaceTokens($senderName, $tokens); $senderName = TextHelper::replaceTokens($senderName, $tokens);
$senderEmail = TextHelper::replaceTokens($senderEmail, $tokens); $senderEmail = TextHelper::replaceTokens($senderEmail, $tokens);
if (empty($recipientEmail))
throw new SimpleException('Destination e-mail address was not found');
$headers = []; $headers = [];
$headers []= sprintf('MIME-Version: 1.0'); $headers []= sprintf('MIME-Version: 1.0');
$headers []= sprintf('Content-Transfer-Encoding: 7bit'); $headers []= sprintf('Content-Transfer-Encoding: 7bit');
@ -71,6 +74,23 @@ class UserController
$tokens); $tokens);
} }
private static function sendPasswordResetConfirmation($user)
{
$regConfig = \Chibi\Registry::getConfig()->registration;
$tokens = [];
$tokens['link'] = \Chibi\UrlHelper::route('user', 'password-reset', ['token' => '{token}']);
return self::sendTokenizedEmail(
$user,
$regConfig->passwordResetEmailBody,
$regConfig->passwordResetEmailSubject,
$regConfig->passwordResetEmailSenderName,
$regConfig->passwordResetEmailSenderEmail,
$user->email_confirmed,
$tokens);
}
/** /**
@ -519,18 +539,7 @@ class UserController
$this->context->subTitle = 'account activation'; $this->context->subTitle = 'account activation';
$this->context->viewName = 'message'; $this->context->viewName = 'message';
if (empty($token)) $dbToken = Model_Token::locate($token);
throw new SimpleException('Invalid activation token');
$dbToken = R::findOne('usertoken', 'token = ?', [$token]);
if ($dbToken === null)
throw new SimpleException('No user with such activation token');
if ($dbToken->used)
throw new SimpleException('This user was already activated');
if ($dbToken->expires !== null and time() > $dbToken->expires)
throw new SimpleException('Activation link expired');
$dbUser = $dbToken->user; $dbUser = $dbToken->user;
$dbUser->email_confirmed = $dbUser->email_unconfirmed; $dbUser->email_confirmed = $dbUser->email_unconfirmed;
@ -554,14 +563,67 @@ class UserController
/** /**
* @route /activation-retry/ * @route /password-reset/{token}
*/ */
public function activationRetryAction() public function passwordResetAction($token)
{ {
$this->context->subTitle = 'activation retry'; $this->context->subTitle = 'password reset';
$this->context->viewName = 'message';
$this->context->stylesheets []= 'auth.css'; $dbToken = Model_Token::locate($token);
$alphabet = array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9'));
$randomPassword = join('', array_map(function($x) use ($alphabet)
{
return $alphabet[$x];
}, array_rand($alphabet, 8)));
$dbUser = $dbToken->user;
$dbUser->pass_hash = Model_User::hashPassword($randomPassword, $dbUser->pass_salt);
$dbToken->used = true;
R::store($dbToken);
R::store($dbUser);
$message = 'Password reset successfuly. Your new password is **' . $randomPassword . '**.';
StatusHelper::success($message);
$this->context->user = $dbUser;
AuthController::doReLog();
}
/**
* @route /password-reset-proxy
*/
public function passwordResetProxyAction()
{
$this->context->subTtile = 'password reset';
$this->context->viewName = 'user-select'; $this->context->viewName = 'user-select';
$this->context->stylesheets []= 'auth.css';
if (InputHelper::get('submit'))
{
$name = InputHelper::get('name');
$user = Model_User::locate($name);
if (empty($user->email_confirmed))
throw new SimpleException('This user has no e-mail confirmed; password reset cannot proceed');
self::sendPasswordResetConfirmation($user);
StatusHelper::success('E-mail sent. Follow instructions to reset password.');
}
}
/**
* @route /activation-proxy
*/
public function activationProxyAction()
{
$this->context->subTitle = 'account activation';
$this->context->viewName = 'user-select';
$this->context->stylesheets []= 'auth.css';
if (InputHelper::get('submit')) if (InputHelper::get('submit'))
{ {
$name = InputHelper::get('name'); $name = InputHelper::get('name');

View file

@ -0,0 +1,25 @@
<?php
class Model_Token extends AbstractModel
{
public static function locate($key, $throw = true)
{
if (empty($key))
throw new SimpleException('Invalid security token');
$token = R::findOne('usertoken', 'token = ?', [$key]);
if ($token === null)
{
if ($throw)
throw new SimpleException('No user with security token');
return null;
}
if ($token->used)
throw new SimpleException('This token was already used');
if ($token->expires !== null and time() > $token->expires)
throw new SimpleException('This token has expired');
return $token;
}
}

View file

@ -35,7 +35,8 @@
<div> <div>
<p>Problems logging in?</p> <p>Problems logging in?</p>
<ul> <ul>
<li><a href="<?php echo \Chibi\UrlHelper::route('user', 'activation-retry') ?>">I haven't received activation e-mail</a></li> <li><a href="<?php echo \Chibi\UrlHelper::route('user', 'password-reset-proxy') ?>">I don't remember my password</a></li>
<li><a href="<?php echo \Chibi\UrlHelper::route('user', 'activation-proxy') ?>">I haven't received activation e-mail</a></li>
<li><a href="<?php echo \Chibi\UrlHelper::route('user', 'registration') ?>">I don't have account</a></li> <li><a href="<?php echo \Chibi\UrlHelper::route('user', 'registration') ?>">I don't have account</a></li>
</ul> </ul>
</div> </div>