Preparation for #62
This commit is contained in:
parent
9ec269330c
commit
fb02feeed3
2 changed files with 120 additions and 28 deletions
|
@ -1,27 +1,36 @@
|
|||
<?php
|
||||
class UserController
|
||||
{
|
||||
private static function sendEmailConfirmation(&$user)
|
||||
private static function sendTokenizedEmail(
|
||||
$user,
|
||||
$body,
|
||||
$subject,
|
||||
$senderName,
|
||||
$senderEmail,
|
||||
$recipientEmail,
|
||||
$tokens)
|
||||
{
|
||||
$regConfig = \Chibi\Registry::getConfig()->registration;
|
||||
|
||||
if (!$regConfig->confirmationEmailEnabled)
|
||||
//prepare unique user token
|
||||
do
|
||||
{
|
||||
$user->email_confirmed = $user->email_unconfirmed;
|
||||
$user->email_unconfirmed = null;
|
||||
return;
|
||||
$tokenText = md5(mt_rand() . uniqid());
|
||||
}
|
||||
while (R::findOne('usertoken', 'token = ?', [$tokenText]) !== null);
|
||||
$token = R::dispense('usertoken');
|
||||
$token->user = $user;
|
||||
$token->token = $tokenText;
|
||||
$token->used = false;
|
||||
$token->expires = null;
|
||||
R::store($token);
|
||||
|
||||
\Chibi\Registry::getContext()->mailSent = true;
|
||||
$tokens = [];
|
||||
$tokens['host'] = $_SERVER['HTTP_HOST'];
|
||||
$tokens['link'] = \Chibi\UrlHelper::route('user', 'activation', ['token' => $user->email_token]);
|
||||
$tokens['token'] = $tokenText;
|
||||
|
||||
$body = wordwrap(TextHelper::replaceTokens($regConfig->confirmationEmailBody, $tokens), 70);
|
||||
$subject = TextHelper::replaceTokens($regConfig->confirmationEmailSubject, $tokens);
|
||||
$senderName = TextHelper::replaceTokens($regConfig->confirmationEmailSenderName, $tokens);
|
||||
$senderEmail = TextHelper::replaceTokens($regConfig->confirmationEmailSenderEmail, $tokens);
|
||||
$recipientEmail = $user->email_unconfirmed;
|
||||
$body = wordwrap(TextHelper::replaceTokens($body, $tokens), 70);
|
||||
$subject = TextHelper::replaceTokens($subject, $tokens);
|
||||
$senderName = TextHelper::replaceTokens($senderName, $tokens);
|
||||
$senderEmail = TextHelper::replaceTokens($senderEmail, $tokens);
|
||||
|
||||
$headers = [];
|
||||
$headers []= sprintf('MIME-Version: 1.0');
|
||||
|
@ -39,6 +48,29 @@ class UserController
|
|||
mail($recipientEmail, $subject, $body, implode("\r\n", $headers), '-f' . $senderEmail);
|
||||
}
|
||||
|
||||
private static function sendEmailChangeConfirmation($user)
|
||||
{
|
||||
$regConfig = \Chibi\Registry::getConfig()->registration;
|
||||
if (!$regConfig->confirmationEmailEnabled)
|
||||
{
|
||||
$user->email_confirmed = $user->email_unconfirmed;
|
||||
$user->email_unconfirmed = null;
|
||||
return;
|
||||
}
|
||||
|
||||
$tokens = [];
|
||||
$tokens['link'] = \Chibi\UrlHelper::route('user', 'activation', ['token' => '{token}']);
|
||||
|
||||
return self::sendTokenizedEmail(
|
||||
$user,
|
||||
$regConfig->confirmationEmailBody,
|
||||
$regConfig->confirmationEmailSubject,
|
||||
$regConfig->confirmationEmailSenderName,
|
||||
$regConfig->confirmationEmailSenderEmail,
|
||||
$user->email_unconfirmed,
|
||||
$tokens);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -250,6 +282,8 @@ class UserController
|
|||
|
||||
if (InputHelper::get('submit'))
|
||||
{
|
||||
$confirmMail = false;
|
||||
|
||||
if ($suppliedName != '' and $suppliedName != $user->name)
|
||||
{
|
||||
PrivilegesHelper::confirmWithException(Privilege::ChangeUserName, PrivilegesHelper::getIdentitySubPrivilege($user));
|
||||
|
@ -274,7 +308,7 @@ class UserController
|
|||
{
|
||||
$user->email_unconfirmed = $suppliedEmail;
|
||||
if (!empty($user->email_unconfirmed))
|
||||
self::sendEmailConfirmation($user);
|
||||
$confirmMail = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -296,6 +330,10 @@ class UserController
|
|||
throw new SimpleException('Must supply valid current password');
|
||||
}
|
||||
R::store($user);
|
||||
|
||||
if ($confirmMail)
|
||||
self::sendEmailChangeConfirmation($user);
|
||||
|
||||
$this->context->transport->success = true;
|
||||
}
|
||||
}
|
||||
|
@ -425,17 +463,10 @@ class UserController
|
|||
$dbUser->pass_hash = Model_User::hashPassword($suppliedPassword, $dbUser->pass_salt);
|
||||
$dbUser->email_unconfirmed = $suppliedEmail;
|
||||
|
||||
//prepare unique registration token
|
||||
do
|
||||
{
|
||||
$emailToken = md5(mt_rand() . uniqid());
|
||||
}
|
||||
while (R::findOne('user', 'email_token = ?', [$emailToken]) !== null);
|
||||
$dbUser->email_token = $emailToken;
|
||||
|
||||
$dbUser->join_date = time();
|
||||
if (R::findOne('user') === null)
|
||||
{
|
||||
//very first user
|
||||
$dbUser->access_rank = AccessRank::Admin;
|
||||
$dbUser->staff_confirmed = true;
|
||||
$dbUser->email_unconfirmed = null;
|
||||
|
@ -446,12 +477,14 @@ class UserController
|
|||
$dbUser->access_rank = AccessRank::Registered;
|
||||
$dbUser->staff_confirmed = false;
|
||||
$dbUser->staff_confirmed = null;
|
||||
if (!empty($dbUser->email_unconfirmed))
|
||||
self::sendEmailConfirmation($dbUser);
|
||||
}
|
||||
|
||||
//save the user to db if everything went okay
|
||||
R::store($dbUser);
|
||||
|
||||
if (!empty($dbUser->email_unconfirmed))
|
||||
self::sendEmailChangeConfirmation($dbUser);
|
||||
|
||||
$this->context->transport->success = true;
|
||||
|
||||
if (!$this->config->registration->needEmailForRegistering and !$this->config->registration->staffActivation)
|
||||
|
@ -474,15 +507,21 @@ class UserController
|
|||
if (empty($token))
|
||||
throw new SimpleException('Invalid activation token');
|
||||
|
||||
$dbUser = R::findOne('user', 'email_token = ?', [$token]);
|
||||
if ($dbUser === null)
|
||||
$dbToken = R::findOne('usertoken', 'token = ?', [$token]);
|
||||
if ($dbToken === null)
|
||||
throw new SimpleException('No user with such activation token');
|
||||
|
||||
if (!$dbUser->email_unconfirmed)
|
||||
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->email_confirmed = $dbUser->email_unconfirmed;
|
||||
$dbUser->email_unconfirmed = null;
|
||||
$dbToken->used = true;
|
||||
R::store($dbToken);
|
||||
R::store($dbUser);
|
||||
$this->context->transport->success = true;
|
||||
|
||||
|
|
53
src/Upgrades/Upgrade6.sql
Normal file
53
src/Upgrades/Upgrade6.sql
Normal file
|
@ -0,0 +1,53 @@
|
|||
CREATE TABLE user2
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT,
|
||||
pass_salt TEXT,
|
||||
pass_hash TEXT,
|
||||
staff_confirmed INTEGER,
|
||||
email_unconfirmed TEXT,
|
||||
email_confirmed TEXT,
|
||||
join_date INTEGER,
|
||||
access_rank INTEGER,
|
||||
settings TEXT,
|
||||
banned INTEGER
|
||||
);
|
||||
|
||||
INSERT INTO user2
|
||||
(id,
|
||||
name,
|
||||
pass_salt,
|
||||
pass_hash,
|
||||
staff_confirmed,
|
||||
email_unconfirmed,
|
||||
email_confirmed,
|
||||
join_date,
|
||||
access_rank,
|
||||
settings,
|
||||
banned)
|
||||
SELECT
|
||||
id,
|
||||
name,
|
||||
pass_salt,
|
||||
pass_hash,
|
||||
staff_confirmed,
|
||||
email_unconfirmed,
|
||||
email_confirmed,
|
||||
join_date,
|
||||
access_rank,
|
||||
settings,
|
||||
banned
|
||||
FROM user;
|
||||
|
||||
DROP TABLE user;
|
||||
ALTER TABLE user2 RENAME TO user;
|
||||
|
||||
CREATE TABLE usertoken
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER,
|
||||
token VARCHAR(32),
|
||||
used BOOLEAN,
|
||||
expires INTEGER --TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_fk_usertoken_user_id ON usertoken(user_id);
|
Loading…
Reference in a new issue