diff --git a/public_html/dispatch.php b/public_html/dispatch.php
index b961f615..da953feb 100644
--- a/public_html/dispatch.php
+++ b/public_html/dispatch.php
@@ -151,10 +151,10 @@ $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', '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/{token}', $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);
diff --git a/src/Api/Jobs/ActivateUserEmailJob.php b/src/Api/Jobs/ActivateUserEmailJob.php
new file mode 100644
index 00000000..c47feec0
--- /dev/null
+++ b/src/Api/Jobs/ActivateUserEmailJob.php
@@ -0,0 +1,65 @@
+hasArgument(self::TOKEN))
+ {
+ $user = UserModel::findByNameOrEmail($this->getArgument(self::USER_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');
+ }
+
+ self::sendEmail($user);
+
+ return $user;
+ }
+ else
+ {
+ $tokenText = $this->getArgument(self::TOKEN);
+ $token = TokenModel::findByToken($tokenText);
+ TokenModel::checkValidity($token);
+
+ $user = $token->getUser();
+ $user->confirmEmail();
+ $token->used = true;
+ TokenModel::save($token);
+ UserModel::save($user);
+
+ LogHelper::log('{subject} just activated account', [
+ 'subject' => TextHelper::reprUser($user)]);
+
+ return $user;
+ }
+ }
+
+ public static function sendEmail($user)
+ {
+ $regConfig = getConfig()->registration;
+
+ if (!$regConfig->confirmationEmailEnabled)
+ {
+ $user->confirmEmail();
+ return;
+ }
+
+ $mail = new Mail();
+ $mail->body = $regConfig->confirmationEmailBody;
+ $mail->subject = $regConfig->confirmationEmailSubject;
+ $mail->senderName = $regConfig->confirmationEmailSenderName;
+ $mail->senderEmail = $regConfig->confirmationEmailSenderEmail;
+ $mail->recipientEmail = $user->emailUnconfirmed;
+
+ return Mailer::sendMailWithTokenLink(
+ $user,
+ ['UserController', 'activationAction'],
+ $mail);
+ }
+}
diff --git a/src/Api/Jobs/AddUserJob.php b/src/Api/Jobs/AddUserJob.php
index 6a426207..537f0c25 100644
--- a/src/Api/Jobs/AddUserJob.php
+++ b/src/Api/Jobs/AddUserJob.php
@@ -24,11 +24,8 @@ class AddUserJob extends AbstractJob
Api::enablePrivilegeChecking();
LogHelper::setBuffer([]);
- if ($firstUser and empty($user->emailConfirmed))
- {
- $user->emailConfirmed = $user->emailUnconfirmed;
- $user->emailUnconfirmed = null;
- }
+ if ($firstUser)
+ $user->confirmEmail();
//load the user after edits
$user = UserModel::findById($user->id);
diff --git a/src/Api/Jobs/EditUserEmailJob.php b/src/Api/Jobs/EditUserEmailJob.php
index 375e138e..af3f82a7 100644
--- a/src/Api/Jobs/EditUserEmailJob.php
+++ b/src/Api/Jobs/EditUserEmailJob.php
@@ -16,20 +16,17 @@ class EditUserEmailJob extends AbstractUserJob
if ($oldEmail == $newEmail)
return $user;
+ $user->emailUnconfirmed = $newEmail;
+ $user->emailConfirmed = null;
+
if (Auth::getCurrentUser()->id == $user->id)
{
- $user->emailUnconfirmed = $newEmail;
- $user->emailConfirmed = null;
-
if (!empty($newEmail))
- {
- $this->sendEmail($user);
- }
+ ActivateUserEmailJob::sendEmail($user);
}
else
{
- $user->emailUnconfirmed = null;
- $user->emailConfirmed = $newEmail;
+ $user->confirmEmail();
}
UserModel::save($user);
@@ -50,29 +47,4 @@ class EditUserEmailJob extends AbstractUserJob
Access::getIdentity($this->user),
];
}
-
- //todo: change to private once finished refactors to UserController
- public function sendEmail($user)
- {
- $regConfig = getConfig()->registration;
-
- if (!$regConfig->confirmationEmailEnabled)
- {
- $user->emailUnconfirmed = null;
- $user->emailConfirmed = $user->emailUnconfirmed;
- return;
- }
-
- $mail = new Mail();
- $mail->body = $regConfig->confirmationEmailBody;
- $mail->subject = $regConfig->confirmationEmailSubject;
- $mail->senderName = $regConfig->confirmationEmailSenderName;
- $mail->senderEmail = $regConfig->confirmationEmailSenderEmail;
- $mail->recipientEmail = $user->emailUnconfirmed;
-
- return Mailer::sendMailWithTokenLink(
- $user,
- ['UserController', 'activationAction'],
- $mail);
- }
}
diff --git a/src/Api/Jobs/PasswordResetJob.php b/src/Api/Jobs/PasswordResetJob.php
new file mode 100644
index 00000000..266818fc
--- /dev/null
+++ b/src/Api/Jobs/PasswordResetJob.php
@@ -0,0 +1,64 @@
+hasArgument(self::TOKEN))
+ {
+ $user = UserModel::findByNameOrEmail($this->getArgument(self::USER_NAME));
+
+ if (empty($user->emailConfirmed))
+ throw new SimpleException('This user has no e-mail confirmed; password reset cannot proceed');
+
+ self::sendEmail($user);
+
+ return $user;
+ }
+ else
+ {
+ $tokenText = $this->getArgument(self::TOKEN);
+ $token = TokenModel::findByToken($tokenText);
+ TokenModel::checkValidity($token);
+
+ $alphabet = array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9'));
+ $newPassword = join('', array_map(function($x) use ($alphabet)
+ {
+ return $alphabet[$x];
+ }, array_rand($alphabet, 8)));
+
+ $user = $token->getUser();
+ $user->passHash = UserModel::hashPassword($newPassword, $user->passSalt);
+ $token->used = true;
+ TokenModel::save($token);
+ UserModel::save($user);
+
+ LogHelper::log('{subject} just reset password', [
+ 'subject' => TextHelper::reprUser($user)]);
+
+ $x = new StdClass;
+ $x->user = $user;
+ $x->newPassword = $newPassword;
+ return $x;
+ }
+ }
+
+ public static function sendEmail($user)
+ {
+ $regConfig = getConfig()->registration;
+
+ $mail = new Mail();
+ $mail->body = $regConfig->passwordResetEmailBody;
+ $mail->subject = $regConfig->passwordResetEmailSubject;
+ $mail->senderName = $regConfig->passwordResetEmailSenderName;
+ $mail->senderEmail = $regConfig->passwordResetEmailSenderEmail;
+ $mail->recipientEmail = $user->emailConfirmed;
+
+ return Mailer::sendMailWithTokenLink(
+ $user,
+ ['UserController', 'passwordResetAction'],
+ $mail);
+ }
+}
diff --git a/src/Controllers/UserController.php b/src/Controllers/UserController.php
index b032e439..b8c9a664 100644
--- a/src/Controllers/UserController.php
+++ b/src/Controllers/UserController.php
@@ -223,51 +223,30 @@ class UserController
Assets::setSubTitle('account activation');
}
- public function activationAction($token)
+ public function activationAction($tokenText)
{
$context = getContext();
$context->viewName = 'message';
Assets::setSubTitle('account activation');
+ $name = InputHelper::get('name');
- if (empty($token))
+ if (empty($tokenText))
{
- $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);
+ Api::run(new ActivateUserEmailJob(), [ ActivateUserEmailJob::USER_NAME => $name ]);
+
Messenger::message('Activation e-mail resent.');
}
else
{
- $dbToken = TokenModel::findByToken($token);
- TokenModel::checkValidity($dbToken);
+ $user = Api::run(new ActivateUserEmailJob(), [ ActivateUserEmailJob::TOKEN => $tokenText ]);
- $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);
- }
+ Auth::setCurrentUser($user);
}
}
@@ -278,64 +257,31 @@ class UserController
Assets::setSubTitle('password reset');
}
- public function passwordResetAction($token)
+ public function passwordResetAction($tokenText)
{
$context = getContext();
$context->viewName = 'message';
Assets::setSubTitle('password reset');
+ $name = InputHelper::get('name');
- if (empty($token))
+ if (empty($tokenText))
{
- $name = InputHelper::get('name');
- $user = UserModel::findByNameOrEmail($name);
- if (empty($user->emailConfirmed))
- throw new SimpleException('This user has no e-mail confirmed; password reset cannot proceed');
+ Api::run(new PasswordResetJob(), [ PasswordResetJob::USER_NAME => $name ]);
- self::sendPasswordResetConfirmation($user);
Messenger::message('E-mail sent. Follow instructions to reset password.');
}
else
{
- $dbToken = TokenModel::findByToken($token);
- TokenModel::checkValidity($dbToken);
+ $ret = Api::run(new PasswordResetJob(), [ PasswordResetJob::TOKEN => $tokenText ]);
- $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)));
+ Messenger::message(sprintf(
+ 'Password reset successful. Your new password is **%s**.',
+ $ret->newPassword));
- $dbUser = $dbToken->getUser();
- $dbUser->passHash = UserModel::hashPassword($randomPassword, $dbUser->passSalt);
- $dbToken->used = true;
- TokenModel::save($dbToken);
- UserModel::save($dbUser);
-
- LogHelper::log('{subject} just reset password', ['subject' => TextHelper::reprUser($dbUser)]);
- $message = 'Password reset successful. Your new password is **' . $randomPassword . '**.';
- Messenger::message($message);
-
- Auth::setCurrentUser($dbUser);
+ Auth::setCurrentUser($ret->user);
}
}
- private static function sendPasswordResetConfirmation($user)
- {
- $regConfig = getConfig()->registration;
-
- $mail = new Mail();
- $mail->body = $regConfig->passwordResetEmailBody;
- $mail->subject = $regConfig->passwordResetEmailSubject;
- $mail->senderName = $regConfig->passwordResetEmailSenderName;
- $mail->senderEmail = $regConfig->passwordResetEmailSenderEmail;
- $mail->recipientEmail = $user->emailConfirmed;
-
- return Mailer::sendMailWithTokenLink(
- $user,
- ['UserController', 'passwordResetAction'],
- $mail);
- }
-
private function requirePasswordConfirmation()
{
$user = getContext()->transport->user;
diff --git a/src/Models/Entities/UserEntity.php b/src/Models/Entities/UserEntity.php
index 07a4d7c3..083a8a11 100644
--- a/src/Models/Entities/UserEntity.php
+++ b/src/Models/Entities/UserEntity.php
@@ -112,6 +112,15 @@ class UserEntity extends AbstractEntity
$this->setSetting(UserModel::SETTING_ENDLESS_SCROLLING, $enabled ? 1 : 0);
}
+ public function confirmEmail()
+ {
+ if (!empty($this->emailConfirmed))
+ return;
+
+ $this->emailConfirmed = $user->emailUnconfirmed;
+ $this->emailUnconfirmed = null;
+ }
+
public function hasFavorited($post)
{
$stmt = new Sql\SelectStatement();