Fixed account activation links
This commit is contained in:
parent
1bbba5de3c
commit
329f6a0259
12 changed files with 382 additions and 145 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 5e78e0a68a1188851d12e26c0f58c1ffe95ffb69
|
||||
Subproject commit 3c70aa336c0571d83557d5fe66ff1b5cc0f3478f
|
|
@ -36,130 +36,6 @@ $context->simpleActionName = null;
|
|||
$context->simpleActionName);
|
||||
});
|
||||
|
||||
\Chibi\Router::register(['StaticPagesController', 'mainPageView'], 'GET', '');
|
||||
\Chibi\Router::register(['StaticPagesController', 'mainPageView'], 'GET', '/index');
|
||||
\Chibi\Router::register(['StaticPagesController', 'helpView'], 'GET', '/help');
|
||||
\Chibi\Router::register(['StaticPagesController', 'helpView'], 'GET', '/help/{tab}');
|
||||
|
||||
\Chibi\Router::register(['AuthController', 'loginView'], 'GET', '/auth/login');
|
||||
\Chibi\Router::register(['AuthController', 'loginAction'], 'POST', '/auth/login');
|
||||
\Chibi\Router::register(['AuthController', 'logoutAction'], 'POST', '/auth/logout');
|
||||
\Chibi\Router::register(['AuthController', 'logoutAction'], 'GET', '/auth/logout');
|
||||
|
||||
\Chibi\Router::register(['LogController', 'listView'], 'GET', '/logs');
|
||||
\Chibi\Router::register(['LogController', 'logView'], 'GET', '/log/{name}', ['name' => '[0-9a-zA-Z._-]+']);
|
||||
\Chibi\Router::register(['LogController', 'logView'], 'GET', '/log/{name}/{page}', ['name' => '[0-9a-zA-Z._-]+', 'page' => '\d*']);
|
||||
\Chibi\Router::register(['LogController', 'logView'], 'GET', '/log/{name}/{page}/{filter}', ['name' => '[0-9a-zA-Z._-]+', 'page' => '\d*', 'filter' => '.*']);
|
||||
|
||||
$postValidation =
|
||||
[
|
||||
'tag' => '[^\/]*',
|
||||
'enable' => '0|1',
|
||||
'source' => 'posts|mass-tag',
|
||||
'query' => '[^\/]*',
|
||||
'additionalInfo' => '[^\/]*',
|
||||
'score' => '-1|0|1',
|
||||
];
|
||||
|
||||
\Chibi\Router::register(['PostController', 'uploadView'], 'GET', '/posts/upload', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'uploadAction'], 'POST', '/posts/upload', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'editView'], 'GET', '/post/{id}/edit', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'editAction'], 'POST', '/post/{id}/edit', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'deleteAction'], 'POST', '/post/{id}/delete', $postValidation);
|
||||
|
||||
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}/{query}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}/{query}/{page}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}/{additionalInfo}/{query}/{page}', $postValidation);
|
||||
|
||||
\Chibi\Router::register(['PostController', 'randomView'], 'GET', '/random', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'randomView'], 'GET', '/random/{page}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'favoritesView'], 'GET', '/favorites', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'favoritesView'], 'GET', '/favorites/{page}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'upvotedView'], 'GET', '/upvoted', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'upvotedView'], 'GET', '/upvoted/{page}', $postValidation);
|
||||
|
||||
\Chibi\Router::register(['PostController', 'genericView'], 'GET', '/post/{id}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'fileView'], 'GET', '/post/{name}/retrieve', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'thumbView'], 'GET', '/post/{name}/thumb', $postValidation);
|
||||
|
||||
\Chibi\Router::register(['PostController', 'toggleTagAction'], 'POST', '/post/{id}/toggle-tag/{tag}/{enable}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'flagAction'], 'POST', '/post/{id}/flag', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'hideAction'], 'POST', '/post/{id}/hide', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'unhideAction'], 'POST', '/post/{id}/unhide', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'removeFavoriteAction'], 'POST', '/post/{id}/rem-fav', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'addFavoriteAction'], 'POST', '/post/{id}/add-fav', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'scoreAction'], 'POST', '/post/{id}/score/{score}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'featureAction'], 'POST', '/post/{id}/feature', $postValidation);
|
||||
|
||||
$commentValidation =
|
||||
[
|
||||
'id' => '\d+',
|
||||
'page' => '\d+',
|
||||
];
|
||||
|
||||
\Chibi\Router::register(['CommentController', 'listView'], 'GET', '/comments', $commentValidation);
|
||||
\Chibi\Router::register(['CommentController', 'listView'], 'GET', '/comments/{page}', $commentValidation);
|
||||
\Chibi\Router::register(['CommentController', 'addAction'], 'POST', '/comment/add', $commentValidation);
|
||||
\Chibi\Router::register(['CommentController', 'deleteAction'], 'POST', '/comment/{id}/delete', $commentValidation);
|
||||
\Chibi\Router::register(['CommentController', 'editView'], 'GET', '/comment/{id}/edit', $commentValidation);
|
||||
\Chibi\Router::register(['CommentController', 'editAction'], 'POST', '/comment/{id}/edit', $commentValidation);
|
||||
|
||||
$tagValidation =
|
||||
[
|
||||
'page' => '\d*',
|
||||
'filter' => '[^\/]+',
|
||||
];
|
||||
|
||||
\Chibi\Router::register(['TagController', 'listView'], 'GET', '/tags', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'listView'], 'GET', '/tags/{page}', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'listView'], 'GET', '/tags/{filter}/{page}', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'autoCompleteView'], 'GET', '/tags-autocomplete', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'relatedView'], 'GET', '/tags-related', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'renameView'], 'GET', '/tags-rename', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'renameAction'], 'POST', '/tags-rename', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'mergeView'], 'GET', '/tags-merge', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'mergeAction'], 'POST', '/tags-merge', $tagValidation);
|
||||
|
||||
$userValidation =
|
||||
[
|
||||
'name' => '[^\/]+',
|
||||
'page' => '\d*',
|
||||
'tab' => 'favs|uploads|settings|edit|delete',
|
||||
'filter' => '[^\/]+',
|
||||
];
|
||||
|
||||
\Chibi\Router::register(['UserController', 'listView'], 'GET', '/users', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'listView'], 'GET', '/users/{page}', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'listView'], 'GET', '/users/{filter}/{page}', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'genericView'], 'GET', '/user/{name}/{tab}', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'genericView'], 'GET', '/user/{name}/{tab}/{page}', $userValidation);
|
||||
|
||||
\Chibi\Router::register(['UserController', 'registrationView'], 'GET', '/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/{tokenText}', $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/{tokenText}', $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', 'unbanAction'], 'POST', '/user/{name}/unban', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'acceptRegistrationAction'], 'POST', '/user/{name}/accept-registration', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'deleteAction'], 'POST', '/user/{name}/delete', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'settingsAction'], 'POST', '/user/{name}/settings', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'editAction'], 'POST', '/user/{name}/edit', $userValidation);
|
||||
|
||||
foreach (['GET', 'POST'] as $method)
|
||||
{
|
||||
\Chibi\Router::register(['TagController', 'massTagRedirectAction'], $method, '/mass-tag-redirect', $tagValidation);
|
||||
|
||||
\Chibi\Router::register(['UserController', 'toggleSafetyAction'], $method, '/user/toggle-safety/{safety}', $userValidation);
|
||||
}
|
||||
|
||||
Assets::setTitle($config->main->title);
|
||||
|
||||
$context->handleExceptions = false;
|
||||
|
|
|
@ -29,7 +29,7 @@ class ActivateUserEmailJob extends AbstractJob
|
|||
|
||||
$user = $token->getUser();
|
||||
$user->confirmEmail();
|
||||
$token->used = true;
|
||||
$token->setUsed(true);
|
||||
TokenModel::save($token);
|
||||
UserModel::save($user);
|
||||
|
||||
|
|
|
@ -6,4 +6,6 @@ class Mail
|
|||
public $senderName;
|
||||
public $senderEmail;
|
||||
public $recipientEmail;
|
||||
|
||||
public $tokens;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
<?php
|
||||
class Mailer
|
||||
{
|
||||
private static $mailCounter = 0;
|
||||
private static $mock = false;
|
||||
private static $mailCounter;
|
||||
private static $mailsSent;
|
||||
private static $mock;
|
||||
|
||||
public static function init()
|
||||
{
|
||||
self::$mailCounter = 0;
|
||||
self::$mailsSent = [];
|
||||
self::$mock = false;
|
||||
}
|
||||
|
||||
|
@ -15,6 +17,11 @@ class Mailer
|
|||
return self::$mailCounter;
|
||||
}
|
||||
|
||||
public static function getMailsSent()
|
||||
{
|
||||
return self::$mailsSent;
|
||||
}
|
||||
|
||||
public static function mockSending()
|
||||
{
|
||||
self::$mock = true;
|
||||
|
@ -63,6 +70,8 @@ class Mailer
|
|||
if (!self::$mock)
|
||||
mail($recipientEmail, $encodedSubject, $body, implode("\r\n", $headers), '-f' . $senderEmail);
|
||||
|
||||
$mail->tokens = $tokens;
|
||||
self::$mailsSent []= $mail;
|
||||
self::$mailCounter ++;
|
||||
|
||||
Logger::log('Sending e-mail with subject "{subject}" to {mail}', [
|
||||
|
@ -79,13 +88,13 @@ class Mailer
|
|||
//prepare unique user token
|
||||
$token = TokenModel::spawn();
|
||||
$token->setUser($user);
|
||||
$token->token = TokenModel::forgeUnusedToken();
|
||||
$token->used = false;
|
||||
$token->expires = null;
|
||||
$token->setText(TokenModel::forgeUnusedToken());
|
||||
$token->setUsed(false);
|
||||
$token->setExpirationDate(null);
|
||||
TokenModel::save($token);
|
||||
|
||||
if (!self::$mock)
|
||||
$tokens['link'] = \Chibi\Router::linkTo($linkDestination, ['token' => $token->token]);
|
||||
$tokens['link'] = \Chibi\Router::linkTo($linkDestination, ['tokenText' => $token->getText()]);
|
||||
$tokens['token'] = $token->getText(); //yeah
|
||||
|
||||
return self::sendMail($mail, $tokens);
|
||||
}
|
||||
|
|
|
@ -1,21 +1,56 @@
|
|||
<?php
|
||||
class TokenEntity extends AbstractEntity implements IValidatable
|
||||
{
|
||||
public $userId;
|
||||
public $token;
|
||||
public $used;
|
||||
public $expires;
|
||||
protected $userId;
|
||||
protected $token;
|
||||
protected $used;
|
||||
protected $expires;
|
||||
|
||||
public function validate()
|
||||
{
|
||||
//todo
|
||||
}
|
||||
|
||||
public function getText()
|
||||
{
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
public function setText($tokenText)
|
||||
{
|
||||
$this->token = $tokenText;
|
||||
}
|
||||
|
||||
public function isUsed()
|
||||
{
|
||||
return $this->used;
|
||||
}
|
||||
|
||||
public function setUsed($used)
|
||||
{
|
||||
$this->used = $used;
|
||||
}
|
||||
|
||||
public function getExpirationDate()
|
||||
{
|
||||
return $this->expires;
|
||||
}
|
||||
|
||||
public function setExpirationDate($time)
|
||||
{
|
||||
$this->expires = $time;
|
||||
}
|
||||
|
||||
public function getUser()
|
||||
{
|
||||
return UserModel::findById($this->userId);
|
||||
}
|
||||
|
||||
public function getUserId()
|
||||
{
|
||||
return $this->userId;
|
||||
}
|
||||
|
||||
public function setUser($user)
|
||||
{
|
||||
$this->userId = $user ? $user->getId() : null;
|
||||
|
|
|
@ -18,10 +18,10 @@ class TokenModel extends AbstractCrudModel
|
|||
self::forgeId($token);
|
||||
|
||||
$bindings = [
|
||||
'user_id' => $token->userId,
|
||||
'token' => $token->token,
|
||||
'used' => $token->used,
|
||||
'expires' => $token->expires,
|
||||
'user_id' => $token->getUserId(),
|
||||
'token' => $token->getText(),
|
||||
'used' => $token->isUsed(),
|
||||
'expires' => $token->getExpirationDate(),
|
||||
];
|
||||
|
||||
$stmt = new Sql\UpdateStatement();
|
||||
|
@ -61,10 +61,10 @@ class TokenModel extends AbstractCrudModel
|
|||
if (empty($token))
|
||||
throw new SimpleException('Invalid security token');
|
||||
|
||||
if ($token->used)
|
||||
if ($token->isUsed())
|
||||
throw new SimpleException('This token was already used');
|
||||
|
||||
if ($token->expires !== null and time() > $token->expires)
|
||||
if ($token->getExpirationDate() !== null and time() > $token->getExpirationDate())
|
||||
throw new SimpleException('This token has expired');
|
||||
}
|
||||
|
||||
|
|
|
@ -120,12 +120,15 @@ class UserModel extends AbstractCrudModel
|
|||
|
||||
public static function findByNameOrEmail($key, $throw = true)
|
||||
{
|
||||
$key = trim($key);
|
||||
|
||||
$stmt = new Sql\SelectStatement();
|
||||
$stmt->setColumn('*');
|
||||
$stmt->setTable('user');
|
||||
$stmt->setCriterion((new Sql\DisjunctionFunctor)
|
||||
->add(new Sql\NoCaseFunctor(new Sql\EqualsFunctor('name', new Sql\Binding(trim($key)))))
|
||||
->add(new Sql\NoCaseFunctor(new Sql\EqualsFunctor('email_confirmed', new Sql\Binding(trim($key))))));
|
||||
->add(new Sql\NoCaseFunctor(new Sql\EqualsFunctor('name', new Sql\Binding($key))))
|
||||
->add(new Sql\NoCaseFunctor(new Sql\EqualsFunctor('email_unconfirmed', new Sql\Binding($key))))
|
||||
->add(new Sql\NoCaseFunctor(new Sql\EqualsFunctor('email_confirmed', new Sql\Binding($key)))));
|
||||
|
||||
$row = Database::fetchOne($stmt);
|
||||
if ($row)
|
||||
|
|
|
@ -20,6 +20,8 @@ require_once $rootDir . 'lib' . DS . 'chibi-core' . DS . 'include.php';
|
|||
\Chibi\AutoLoader::registerFilesystem($rootDir . 'lib' . DS . 'chibi-sql');
|
||||
\Chibi\AutoLoader::registerFilesystem(__DIR__);
|
||||
|
||||
require_once $rootDir . 'src' . DS . 'routes.php';
|
||||
|
||||
function getConfig()
|
||||
{
|
||||
global $config;
|
||||
|
|
119
src/routes.php
Normal file
119
src/routes.php
Normal file
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
\Chibi\Router::register(['StaticPagesController', 'mainPageView'], 'GET', '');
|
||||
\Chibi\Router::register(['StaticPagesController', 'mainPageView'], 'GET', '/index');
|
||||
\Chibi\Router::register(['StaticPagesController', 'helpView'], 'GET', '/help');
|
||||
\Chibi\Router::register(['StaticPagesController', 'helpView'], 'GET', '/help/{tab}');
|
||||
|
||||
\Chibi\Router::register(['AuthController', 'loginView'], 'GET', '/auth/login');
|
||||
\Chibi\Router::register(['AuthController', 'loginAction'], 'POST', '/auth/login');
|
||||
\Chibi\Router::register(['AuthController', 'logoutAction'], 'POST', '/auth/logout');
|
||||
\Chibi\Router::register(['AuthController', 'logoutAction'], 'GET', '/auth/logout');
|
||||
|
||||
\Chibi\Router::register(['LogController', 'listView'], 'GET', '/logs');
|
||||
\Chibi\Router::register(['LogController', 'logView'], 'GET', '/log/{name}', ['name' => '[0-9a-zA-Z._-]+']);
|
||||
\Chibi\Router::register(['LogController', 'logView'], 'GET', '/log/{name}/{page}', ['name' => '[0-9a-zA-Z._-]+', 'page' => '\d*']);
|
||||
\Chibi\Router::register(['LogController', 'logView'], 'GET', '/log/{name}/{page}/{filter}', ['name' => '[0-9a-zA-Z._-]+', 'page' => '\d*', 'filter' => '.*']);
|
||||
|
||||
$postValidation =
|
||||
[
|
||||
'tag' => '[^\/]*',
|
||||
'enable' => '0|1',
|
||||
'source' => 'posts|mass-tag',
|
||||
'query' => '[^\/]*',
|
||||
'additionalInfo' => '[^\/]*',
|
||||
'score' => '-1|0|1',
|
||||
];
|
||||
|
||||
\Chibi\Router::register(['PostController', 'uploadView'], 'GET', '/posts/upload', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'uploadAction'], 'POST', '/posts/upload', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'editView'], 'GET', '/post/{id}/edit', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'editAction'], 'POST', '/post/{id}/edit', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'deleteAction'], 'POST', '/post/{id}/delete', $postValidation);
|
||||
|
||||
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}/{query}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}/{query}/{page}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'listView'], 'GET', '/{source}/{additionalInfo}/{query}/{page}', $postValidation);
|
||||
|
||||
\Chibi\Router::register(['PostController', 'randomView'], 'GET', '/random', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'randomView'], 'GET', '/random/{page}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'favoritesView'], 'GET', '/favorites', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'favoritesView'], 'GET', '/favorites/{page}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'upvotedView'], 'GET', '/upvoted', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'upvotedView'], 'GET', '/upvoted/{page}', $postValidation);
|
||||
|
||||
\Chibi\Router::register(['PostController', 'genericView'], 'GET', '/post/{id}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'fileView'], 'GET', '/post/{name}/retrieve', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'thumbView'], 'GET', '/post/{name}/thumb', $postValidation);
|
||||
|
||||
\Chibi\Router::register(['PostController', 'toggleTagAction'], 'POST', '/post/{id}/toggle-tag/{tag}/{enable}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'flagAction'], 'POST', '/post/{id}/flag', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'hideAction'], 'POST', '/post/{id}/hide', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'unhideAction'], 'POST', '/post/{id}/unhide', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'removeFavoriteAction'], 'POST', '/post/{id}/rem-fav', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'addFavoriteAction'], 'POST', '/post/{id}/add-fav', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'scoreAction'], 'POST', '/post/{id}/score/{score}', $postValidation);
|
||||
\Chibi\Router::register(['PostController', 'featureAction'], 'POST', '/post/{id}/feature', $postValidation);
|
||||
|
||||
$commentValidation =
|
||||
[
|
||||
'id' => '\d+',
|
||||
'page' => '\d+',
|
||||
];
|
||||
|
||||
\Chibi\Router::register(['CommentController', 'listView'], 'GET', '/comments', $commentValidation);
|
||||
\Chibi\Router::register(['CommentController', 'listView'], 'GET', '/comments/{page}', $commentValidation);
|
||||
\Chibi\Router::register(['CommentController', 'addAction'], 'POST', '/comment/add', $commentValidation);
|
||||
\Chibi\Router::register(['CommentController', 'deleteAction'], 'POST', '/comment/{id}/delete', $commentValidation);
|
||||
\Chibi\Router::register(['CommentController', 'editView'], 'GET', '/comment/{id}/edit', $commentValidation);
|
||||
\Chibi\Router::register(['CommentController', 'editAction'], 'POST', '/comment/{id}/edit', $commentValidation);
|
||||
|
||||
$tagValidation =
|
||||
[
|
||||
'page' => '\d*',
|
||||
'filter' => '[^\/]+',
|
||||
];
|
||||
|
||||
\Chibi\Router::register(['TagController', 'listView'], 'GET', '/tags', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'listView'], 'GET', '/tags/{page}', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'listView'], 'GET', '/tags/{filter}/{page}', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'autoCompleteView'], 'GET', '/tags-autocomplete', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'relatedView'], 'GET', '/tags-related', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'renameView'], 'GET', '/tags-rename', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'renameAction'], 'POST', '/tags-rename', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'mergeView'], 'GET', '/tags-merge', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'mergeAction'], 'POST', '/tags-merge', $tagValidation);
|
||||
\Chibi\Router::register(['TagController', 'massTagRedirectAction'], 'GET', '/mass-tag-redirect', $tagValidation);
|
||||
|
||||
$userValidation =
|
||||
[
|
||||
'name' => '[^\/]+',
|
||||
'page' => '\d*',
|
||||
'tab' => 'favs|uploads|settings|edit|delete',
|
||||
'filter' => '[^\/]+',
|
||||
];
|
||||
|
||||
\Chibi\Router::register(['UserController', 'listView'], 'GET', '/users', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'listView'], 'GET', '/users/{page}', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'listView'], 'GET', '/users/{filter}/{page}', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'genericView'], 'GET', '/user/{name}/{tab}', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'genericView'], 'GET', '/user/{name}/{tab}/{page}', $userValidation);
|
||||
|
||||
\Chibi\Router::register(['UserController', 'registrationView'], 'GET', '/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/{tokenText}', $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/{tokenText}', $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', 'unbanAction'], 'POST', '/user/{name}/unban', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'acceptRegistrationAction'], 'POST', '/user/{name}/accept-registration', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'deleteAction'], 'POST', '/user/{name}/delete', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'settingsAction'], 'POST', '/user/{name}/settings', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'editAction'], 'POST', '/user/{name}/edit', $userValidation);
|
||||
\Chibi\Router::register(['UserController', 'toggleSafetyAction'], 'POST', '/user/toggle-safety/{safety}', $userValidation);
|
149
tests/JobTests/ActivateUserEmailJobTest.php
Normal file
149
tests/JobTests/ActivateUserEmailJobTest.php
Normal file
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
class ActivateUserEmailJobTest extends AbstractTest
|
||||
{
|
||||
public function testSending()
|
||||
{
|
||||
getConfig()->registration->needEmailForRegistering = true;
|
||||
Mailer::mockSending();
|
||||
|
||||
$user = $this->mockUser();
|
||||
$user->setUnconfirmedEmail('godzilla@whitestar.gov');
|
||||
UserModel::save($user);
|
||||
|
||||
$this->assert->areEqual(0, Mailer::getMailCounter());
|
||||
|
||||
$this->assert->doesNotThrow(function() use ($user)
|
||||
{
|
||||
Api::run(
|
||||
new ActivateUserEmailJob(),
|
||||
[
|
||||
ActivateUserEmailJob::USER_NAME => $user->getName(),
|
||||
]);
|
||||
});
|
||||
|
||||
$this->assert->areEqual(1, Mailer::getMailCounter());
|
||||
|
||||
$tokens = Mailer::getMailsSent()[0]->tokens;
|
||||
$tokenText = $tokens['token'];
|
||||
$token = TokenModel::findByToken($tokenText);
|
||||
|
||||
$this->assert->areEqual($user->getId(), $token->getUser()->getId());
|
||||
$this->assert->isTrue(strpos($tokens['link'], $tokenText) !== false);
|
||||
|
||||
return $tokenText;
|
||||
}
|
||||
|
||||
public function testConfirming()
|
||||
{
|
||||
getConfig()->registration->needEmailForRegistering = true;
|
||||
Mailer::mockSending();
|
||||
|
||||
$user = $this->mockUser();
|
||||
$user->setUnconfirmedEmail('godzilla@whitestar.gov');
|
||||
UserModel::save($user);
|
||||
|
||||
$this->assert->areEqual('godzilla@whitestar.gov', $user->getUnconfirmedEmail());
|
||||
$this->assert->areEqual(null, $user->getConfirmedEmail());
|
||||
|
||||
$this->assert->doesNotThrow(function() use ($user)
|
||||
{
|
||||
Api::run(
|
||||
new ActivateUserEmailJob(),
|
||||
[
|
||||
ActivateUserEmailJob::USER_NAME => $user->getName(),
|
||||
]);
|
||||
});
|
||||
|
||||
$tokenText = Mailer::getMailsSent()[0]->tokens['token'];
|
||||
|
||||
$this->assert->doesNotThrow(function() use ($tokenText)
|
||||
{
|
||||
Api::run(
|
||||
new ActivateUserEmailJob(),
|
||||
[
|
||||
ActivateUserEmailJob::TOKEN => $tokenText,
|
||||
]);
|
||||
});
|
||||
|
||||
//reload local entity after changes done by the job
|
||||
$user = UserModel::findById($user->getId());
|
||||
|
||||
$this->assert->areEqual(null, $user->getUnconfirmedEmail());
|
||||
$this->assert->areEqual('godzilla@whitestar.gov', $user->getConfirmedEmail());
|
||||
}
|
||||
|
||||
|
||||
public function testUsingTokenTwice()
|
||||
{
|
||||
getConfig()->registration->needEmailForRegistering = true;
|
||||
Mailer::mockSending();
|
||||
|
||||
$user = $this->mockUser();
|
||||
$user->setUnconfirmedEmail('godzilla@whitestar.gov');
|
||||
UserModel::save($user);
|
||||
|
||||
$this->assert->areEqual('godzilla@whitestar.gov', $user->getUnconfirmedEmail());
|
||||
$this->assert->areEqual(null, $user->getConfirmedEmail());
|
||||
|
||||
Api::run(
|
||||
new ActivateUserEmailJob(),
|
||||
[
|
||||
ActivateUserEmailJob::USER_NAME => $user->getName(),
|
||||
]);
|
||||
|
||||
$tokenText = Mailer::getMailsSent()[0]->tokens['token'];
|
||||
|
||||
Api::run(
|
||||
new ActivateUserEmailJob(),
|
||||
[
|
||||
ActivateUserEmailJob::TOKEN => $tokenText,
|
||||
]);
|
||||
|
||||
$this->assert->throws(function() use ($tokenText)
|
||||
{
|
||||
Api::run(
|
||||
new ActivateUserEmailJob(),
|
||||
[
|
||||
ActivateUserEmailJob::TOKEN => $tokenText,
|
||||
]);
|
||||
}, 'This token was already used');
|
||||
}
|
||||
|
||||
public function testTokensTwoUsersSameMail()
|
||||
{
|
||||
getConfig()->registration->needEmailForRegistering = true;
|
||||
Mailer::mockSending();
|
||||
|
||||
$user1 = $this->mockUser();
|
||||
$user2 = $this->mockUser();
|
||||
$user1->setUnconfirmedEmail('godzilla@whitestar.gov');
|
||||
$user2->setUnconfirmedEmail('godzilla@whitestar.gov');
|
||||
UserModel::save($user1);
|
||||
UserModel::save($user2);
|
||||
|
||||
Api::run(
|
||||
new ActivateUserEmailJob(),
|
||||
[
|
||||
ActivateUserEmailJob::USER_NAME => $user1->getName(),
|
||||
]);
|
||||
|
||||
Api::run(
|
||||
new ActivateUserEmailJob(),
|
||||
[
|
||||
ActivateUserEmailJob::USER_NAME => $user2->getName(),
|
||||
]);
|
||||
|
||||
$tokens1 = Mailer::getMailsSent()[0]->tokens;
|
||||
$tokens2 = Mailer::getMailsSent()[1]->tokens;
|
||||
$token1text = $tokens1['token'];
|
||||
$token2text = $tokens2['token'];
|
||||
$this->assert->areNotEqual($token1text, $token2text);
|
||||
|
||||
$token1 = TokenModel::findByToken($token1text);
|
||||
$token2 = TokenModel::findByToken($token2text);
|
||||
|
||||
$this->assert->areEqual($user1->getId(), $token1->getUser()->getId());
|
||||
$this->assert->areEqual($user2->getId(), $token2->getUser()->getId());
|
||||
$this->assert->areNotEqual($token1->getUserId(), $token2->getUserId());
|
||||
}
|
||||
}
|
|
@ -263,6 +263,48 @@ class AddUserJobTest extends AbstractTest
|
|||
$this->assert->areEqual(0, Mailer::getMailCounter());
|
||||
}
|
||||
|
||||
public function testEmailsTwoUsersSameMail()
|
||||
{
|
||||
getConfig()->registration->needEmailForRegistering = true;
|
||||
Mailer::mockSending();
|
||||
$this->assert->areEqual(0, Mailer::getMailCounter());
|
||||
|
||||
$this->grantAccess('registerAccount');
|
||||
|
||||
$user1 = $this->assert->doesNotThrow(function()
|
||||
{
|
||||
return Api::run(
|
||||
new AddUserJob(),
|
||||
[
|
||||
EditUserNameJob::NEW_USER_NAME => 'dummy',
|
||||
EditUserPasswordJob::NEW_PASSWORD => 'sekai',
|
||||
EditUserEmailJob::NEW_EMAIL => 'godzilla@whitestar.gov',
|
||||
]);
|
||||
});
|
||||
|
||||
$user2 = $this->assert->doesNotThrow(function()
|
||||
{
|
||||
return Api::run(
|
||||
new AddUserJob(),
|
||||
[
|
||||
EditUserNameJob::NEW_USER_NAME => 'dummy2',
|
||||
EditUserPasswordJob::NEW_PASSWORD => 'sekai',
|
||||
EditUserEmailJob::NEW_EMAIL => 'godzilla@whitestar.gov',
|
||||
]);
|
||||
});
|
||||
|
||||
$this->assert->areEqual(2, Mailer::getMailCounter());
|
||||
$token1text = Mailer::getMailsSent()[0]->tokens['token'];
|
||||
$token2text = Mailer::getMailsSent()[1]->tokens['token'];
|
||||
$this->assert->areNotEqual($token1text, $token2text);
|
||||
|
||||
$token1 = TokenModel::findByToken($token1text);
|
||||
$token2 = TokenModel::findByToken($token2text);
|
||||
|
||||
$this->assert->areEqual($user1->getId(), $token1->getUser()->getId());
|
||||
$this->assert->areEqual($user2->getId(), $token2->getUser()->getId());
|
||||
}
|
||||
|
||||
public function testLogBuffering()
|
||||
{
|
||||
$this->testSaving();
|
||||
|
|
Loading…
Reference in a new issue