r20160228

This commit is contained in:
flash 2016-02-28 18:45:25 +01:00
parent 03ba7e9ffe
commit 370e38a9ff
13 changed files with 366 additions and 482 deletions

View file

@ -79,6 +79,7 @@ class AuthController extends Controller
if (Config::get('lock_authentication')) {
$message = 'Logging in is disabled for security checkups! Try again later.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
@ -97,6 +98,7 @@ class AuthController extends Controller
if ($rates > 4) {
$message = 'Your have hit the login rate limit, try again later.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
@ -108,6 +110,7 @@ class AuthController extends Controller
$this->touchRateLimit($user->id);
$message = 'The user you tried to log into does not exist.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
@ -118,6 +121,7 @@ class AuthController extends Controller
$this->touchRateLimit($user->id);
$message = 'Logging into this account is disabled.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
// Default hashing method
@ -131,6 +135,7 @@ class AuthController extends Controller
$this->touchRateLimit($user->id);
$message = 'The password you entered was invalid.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
}
@ -140,6 +145,7 @@ class AuthController extends Controller
$this->touchRateLimit($user->id);
$message = 'Your account does not have the required permissions to log in.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
@ -175,4 +181,179 @@ class AuthController extends Controller
return Template::render('global/information');
}
public function registerGet()
{
// Attempt to check if a user has already registered from the current IP
$getUserIP = DB::table('users')
->where('register_ip', Net::pton(Net::IP()))
->orWhere('last_ip', Net::pton(Net::IP()))
->get();
Template::vars([
'haltRegistration' => count($getUserIP) > 1,
'haltName' => $getUserIP[array_rand($getUserIP)]->username,
]);
return Template::render('main/register');
}
public function registerPost()
{
// Preliminarily set login to failed
$success = 0;
$redirect = Router::route('auth.register');
// Check if authentication is disallowed
if (Config::get('lock_authentication') || Config::get('disable_registration')) {
$message = 'Registration is disabled for security checkups! Try again later.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
// Check if authentication is disallowed
if (!isset($_POST['session']) || $_POST['session'] != session_id()) {
$message = "Your session expired, refreshing the page will most likely fix this!";
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
// Grab forms
$username = isset($_POST['username']) ? $_POST['username'] : null;
$password = isset($_POST['password']) ? $_POST['password'] : null;
$email = isset($_POST['email']) ? $_POST['email'] : null;
$captcha = isset($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : null;
$terms = isset($_POST['tos']);
// Append username and email to the redirection url
$redirect .= "?username={$username}&email={$email}";
// Check if the user agreed to the ToS
if (!$terms) {
$message = 'You are required to agree to the Terms of Service.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
// Check if we require a captcha
if (Config::get('recaptcha')) {
// Get secret key from the config
$secret = Config::get('recaptcha_private');
// Attempt to verify the captcha
$response = Net::fetch("https://google.com/recaptcha/api/siteverify?secret={$secret}&response={$captcha}");
// Attempt to decode as json
if ($response) {
$response = json_decode($response);
}
if (!$response || !$response->success) {
$message = 'Captcha verification failed, please try again.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
}
// Attempt to get account data
$user = User::construct(Utils::cleanString($username, true, true));
// Check if the username already exists
if ($user && $user->id !== 0) {
$message = "{$user->username} is already a member here! If this is you please use the password reset form instead of making a new account.";
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
// Username too short
if (strlen($username) < Config::get('username_min_length')) {
$message = 'Your name must be at least 3 characters long.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
// Username too long
if (strlen($username) > Config::get('username_max_length')) {
$message = 'Your name can\'t be longer than 16 characters.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
// Check if the given email address is formatted properly
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$message = 'Your e-mail address is formatted incorrectly.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
// Check the MX record of the email
if (!Utils::checkMXRecord($email)) {
$message = 'No valid MX-Record found on the e-mail address you supplied.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
// Check if the e-mail has already been used
$emailCheck = DB::table('users')
->where('email', $email)
->count();
if ($emailCheck) {
$message = 'Someone already registered using this email!';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
// Check password entropy
if (Utils::pwdEntropy($password) < Config::get('min_entropy')) {
$message = 'Your password is too weak, try adding some special characters.';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
// Set a few variables
$requireActive = Config::get('require_activation');
$ranks = $requireActive ? [1] : [2];
// Create the user
$user = User::create($username, $password, $email, $ranks);
// Check if we require e-mail activation
if ($requireActive) {
// Send activation e-mail to user
Users::sendActivationMail($user->id);
}
// Return true with a specific message if needed
$success = 1;
$redirect = Router::route('auth.login');
$message = $requireActive
? 'Your registration went through! An activation e-mail has been sent.'
: 'Your registration went through! Welcome to ' . Config::get('sitename') . '!';
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
return Template::render('global/information');
}
}

View file

@ -210,4 +210,30 @@ class Net
// Compare them
return ($ip & $mask) === $net;
}
/**
* Fetch a remote file
*
* @param string $url The location of the file
*
* @return mixed The contents of the remote file
*/
public static function fetch($url)
{
// Create a curl instance
$curl = curl_init();
// Set options
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl, CURLOPT_TIMEOUT, 4);
curl_setopt($curl, CURLOPT_USERAGENT, 'Sakura/' . SAKURA_VERSION);
// Execute
$curl = curl_exec($curl);
// Return the data
return $curl;
}
}

View file

@ -166,7 +166,7 @@ class User
public $background = 0;
/**
* The FIle id of the user's header.
* The File id of the user's header.
* @var mixed
*/
public $header = 0;
@ -257,26 +257,23 @@ class User
$emailClean = Utils::cleanString($email, true);
$password = Hashing::createHash($password);
// Insert the user into the database
DBv2::prepare('INSERT INTO `{prefix}users` (`username`, `username_clean`, `password_hash`, `password_salt`, `password_algo`, `password_iter`, `email`, `rank_main`, `register_ip`, `last_ip`, `user_registered`, `user_last_online`, `user_country`) VALUES (:uname, :uname_clean, :pw_hash, :pw_salt, :pw_algo, :pw_iter, :email, :rank, :r_ip, :l_ip, :registered, :l_online, :country)')
->execute([
'uname' => $username,
'uname_clean' => $usernameClean,
'pw_hash' => $password[3],
'pw_salt' => $password[2],
'pw_algo' => $password[0],
'pw_iter' => $password[1],
'email' => $emailClean,
'rank' => 0,
'r_ip' => Net::pton(Net::IP()),
'l_ip' => Net::pton(Net::IP()),
'registered' => time(),
'l_online' => 0,
'country' => Utils::getCountryCode(),
]);
// Get the last id
$userId = DBv2::lastID();
// Insert the user into the database and get the id
$userId = DB::table('users')
->insertGetId([
'username' => $username,
'username_clean' => $usernameClean,
'password_hash' => $password[3],
'password_salt' => $password[2],
'password_algo' => $password[0],
'password_iter' => $password[1],
'email' => $emailClean,
'rank_main' => 0,
'register_ip' => Net::pton(Net::IP()),
'last_ip' => Net::pton(Net::IP()),
'user_registered' => time(),
'user_last_online' => 0,
'user_country' => Utils::getCountryCode(),
]);
// Create a user object
$user = self::construct($userId);
@ -294,20 +291,19 @@ class User
/**
* The actual constructor
*
* @param int|string $uid The user ID or clean username.
* @param int|string $userId The user ID or clean username.
*/
private function __construct($uid)
private function __construct($userId)
{
// Get the user database row
$userRow = DBv2::prepare('SELECT * FROM `{prefix}users` WHERE `user_id` = :id OR `username_clean` = :clean');
$userRow->execute([
'id' => $uid,
'clean' => Utils::cleanString($uid, true, true),
]);
$userRow = $userRow->fetch();
$userRow = DB::table('users')
->where('user_id', $userId)
->orWhere('username_clean', Utils::cleanString($userId, true, true))
->get();
// Populate the variables
if ($userRow) {
$userRow = $userRow[0];
$this->id = $userRow->user_id;
$this->username = $userRow->username;
$this->usernameClean = $userRow->username_clean;
@ -319,8 +315,8 @@ class User
$this->email = $userRow->email;
$this->mainRankId = $userRow->rank_main;
$this->colour = $userRow->user_colour;
$this->registerIp = $userRow->register_ip;
$this->lastIp = $userRow->last_ip;
$this->registerIp = Net::ntop($userRow->register_ip);
$this->lastIp = Net::ntop($userRow->last_ip);
$this->title = $userRow->user_title;
$this->registered = $userRow->user_registered;
$this->lastOnline = $userRow->user_last_online;
@ -334,11 +330,9 @@ class User
}
// Get all ranks
$ranks = DBv2::prepare('SELECT * FROM `{prefix}user_ranks` WHERE `user_id` = :id');
$ranks->execute([
'id' => $this->id,
]);
$ranks = $ranks->fetchAll();
$ranks = DB::table('user_ranks')
->where('user_id', $this->id)
->get(['rank_id']);
// Get the rows for all the ranks
foreach ($ranks as $rank) {
@ -371,15 +365,6 @@ class User
$this->permissions = new Perms(Perms::SITE);
}
/**
* Commit changed to database, doesn't do anything yet.
*/
public function update()
{
// placeholder
}
/**
* Get the user's birthday.
*
@ -425,14 +410,13 @@ class User
*/
public function isOnline()
{
// Get all sessions
$sessions = DBv2::prepare('SELECT `user_id` FROM `{prefix}sessions` WHERE `user_id` = :id');
$sessions->execute([
'id' => $this->id,
]);
// Count sessions
$sessions = DB::table('sessions')
->where('user_id', $this->id)
->count();
// If there's no entries just straight up return false
if (!$sessions->rowCount()) {
if (!$sessions) {
return false;
}
@ -447,19 +431,20 @@ class User
*/
public function forumStats()
{
$posts = DBv2::prepare('SELECT * FROM `{prefix}posts` WHERE `poster_id` = :id');
$posts->execute([
'id' => $this->id,
]);
$posts = DB::table('posts')
->where('poster_id', $this->id)
->count();
$threads = DBv2::prepare('SELECT DISTINCT * FROM `{prefix}posts` WHERE `poster_id` = :id GROUP BY `topic_id` ORDER BY `post_time`');
$threads->execute([
'id' => $this->id,
]);
$threads = DB::table('posts')
->where('poster_id', $this->id)
->distinct()
->groupBy('topic_id')
->orderBy('post_time')
->count();
return [
'posts' => $posts->rowCount(),
'topics' => $threads->rowCount(),
'posts' => $posts,
'topics' => $threads,
];
}
@ -482,11 +467,11 @@ class User
// Save to the database
foreach ($ranks as $rank) {
DBv2::prepare('INSERT INTO `{prefix}ranks` (`rank_id`, `user_id`) VALUES (:rank, :user)')
->execute([
'rank' => $rank,
'user' => $this->id,
]);
DB::table('user_ranks')
->insert([
'rank_id' => $rank,
'user_id' => $this->id,
]);
}
}
@ -502,11 +487,10 @@ class User
// Iterate over the ranks
foreach ($remove as $rank) {
DBv2::prepare('DELETE FROM `{prefix}user_ranks` WHERE `user_id` = :user AND `rank_id` = :rank')
->execute([
'user' => $this->id,
'rank' => $rank,
]);
DB::table('ranks')
->where('user_id', $this->id)
->where('rank_id', $rank)
->delete();
}
}
@ -520,11 +504,11 @@ class User
public function setMainRank($rank)
{
// If it does exist update their row
DBv2::prepare('UPDATE `{prefix}users` SET `rank_main` = :rank WHERE `user_id` = :id')
->execute([
'rank' => $rank,
'id' => $this->id,
]);
DB::table('users')
->where('user_id', $this->id)
->update([
'rank_main' => $rank,
]);
// Return true if everything was successful
return true;
@ -579,12 +563,12 @@ class User
}
// Add friend
DBv2::prepare('INSERT INTO `{prefix}friends` (`user_id`, `friend_id`, `friend_timestamp`) VALUES (:user, :friend, :time)')
->execute([
'user' => $this->id,
'friend' => $uid,
'time' => time(),
]);
DB::table('friends')
->insert([
'user_id' => $this->id,
'friend_id' => $uid,
'friend_timestamp' => time(),
]);
// Return true because yay
return [1, $user->isFriends($this->id) ? 'FRIENDS' : 'NOT_MUTUAL'];
@ -873,7 +857,7 @@ class User
}
// Check if we have additional options as well
if (!$field['field_additional']) {
if ($field['field_additional'] != null) {
// Decode the json of the additional stuff
$additional = json_decode($field['field_additional'], true);

View file

@ -98,104 +98,6 @@ class Users
return [$uid, $sid];
}
/**
* Register a new account.
*
* @param string $username The username.
* @param string $password The password.
* @param string $confirmpass The password, again.
* @param string $email The e-mail.
* @param bool $tos Agreeing to the ToS.
* @param string $captcha Captcha.
* @param string $regkey Registration key (unused).
*
* @return array Status.
*/
public static function register($username, $password, $confirmpass, $email, $tos, $captcha = null, $regkey = null)
{
// Check if authentication is disallowed
if (Config::get('lock_authentication')) {
return [0, 'AUTH_LOCKED'];
}
// Check if registration is even enabled
if (Config::get('disable_registration')) {
return [0, 'DISABLED'];
}
// Check if the user agreed to the ToS
if (!$tos) {
return [0, 'TOS'];
}
// Verify the captcha if it's enabled
if (Config::get('recaptcha')) {
if (!Utils::verifyCaptcha($captcha)['success']) {
return [0, 'CAPTCHA_FAIL'];
}
}
// Check if the username already exists
if (self::userExists($username, false)) {
return [0, 'USER_EXISTS'];
}
// Username too short
if (strlen($username) < Config::get('username_min_length')) {
return [0, 'NAME_TOO_SHORT'];
}
// Username too long
if (strlen($username) > Config::get('username_max_length')) {
return [0, 'NAME_TOO_LONG'];
}
// Check if the given email address is formatted properly
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return [0, 'INVALID_EMAIL'];
}
// Check the MX record of the email
if (!Utils::checkMXRecord($email)) {
return [0, 'INVALID_MX'];
}
// Check if the e-mail has already been used
$emailCheck = DBv2::prepare('SELECT `user_id` FROM `{prefix}users` WHERE `email` = :email');
$emailCheck->execute([
'email' => $email,
]);
if ($emailCheck->rowCount() > 0) {
return [0, 'EMAIL_EXISTS'];
}
// Check password entropy
if (Utils::pwdEntropy($password) < Config::get('min_entropy')) {
return [0, 'PASS_TOO_SHIT'];
}
// Passwords do not match
if ($password != $confirmpass) {
return [0, 'PASS_NOT_MATCH'];
}
// Set a few variables
$requireActive = Config::get('require_activation');
$ranks = $requireActive ? [1] : [2];
// Create the user
$user = User::create($username, $password, $email, $ranks);
// Check if we require e-mail activation
if ($requireActive) {
// Send activation e-mail to user
self::sendActivationMail($user->id);
}
// Return true with a specific message if needed
return [1, ($requireActive ? 'EMAILSENT' : 'SUCCESS')];
}
/**
* Send password forgot e-mail
*
@ -455,28 +357,6 @@ class Users
return [1, 'SUCCESS'];
}
/**
* Check if a user exists.
*
* @param mixed $id The Username or ID.
* @param mixed $unused Unused variable.
*
* @return mixed Returns the ID if it exists, false otherwise.
*/
public static function userExists($id, $unused = null)
{
// Do database request
$user = DBv2::prepare('SELECT * FROM `{prefix}users` WHERE `user_id` = :id OR `username_clean` = :clean');
$user->execute([
'id' => $id,
'clean' => Utils::cleanString($id, true, true),
]);
$user = $user->fetch();
// Return count (which would return 0, aka false, if nothing was found)
return $user ? $user->user_id : false;
}
/**
* Get all available profile fields.
*
@ -649,51 +529,6 @@ class Users
}
}
/**
* Get all users that registered from a certain IP.
*
* @param string $ip The IP.
*
* @return array The users.
*/
public static function getUsersByIP($ip)
{
// Get the users
$users = DBv2::prepare('SELECT * FROM `{prefix}users` WHERE `register_ip` = :rip OR `last_ip` = :lip');
$users->execute([
'rip' => $ip,
'lip' => $ip,
]);
$users = $users->fetchAll(\PDO::FETCH_ASSOC);
// Return the array with users
return $users;
}
/**
* Get all ranks.
*
* @return array All ranks.
*/
public static function getAllRanks()
{
// Execute query
$getRanks = DBv2::prepare('SELECT * FROM `{prefix}ranks`');
$getRanks->execute();
$getRanks = $getRanks->fetchAll();
// Define variable
$ranks = [];
// Reorder shit
foreach ($getRanks as $rank) {
$ranks[$rank->rank_id] = Rank::construct($rank->rank_id);
}
// and return an array with the ranks
return $ranks;
}
/**
* Get a user's notifications.
*

View file

@ -17,35 +17,6 @@ use PHPMailer;
*/
class Utils
{
/**
* Verify a ReCaptcha
*
* @param string $response The user response.
*
* @return array The response from the ReCaptcha API.
*/
public static function verifyCaptcha($response)
{
// Attempt to get the response
$resp = file_get_contents(
'https://www.google.com/recaptcha/api/siteverify?secret='
. Config::get('recaptcha_private')
. '&response='
. $response
);
// In the highly unlikely case that it failed to get anything forge a false
if (!$resp) {
return [];
}
// Decode the response JSON from the servers
$resp = json_decode($resp, true);
// Return shit
return $resp;
}
/**
* The error handler.
*
@ -60,42 +31,6 @@ class Utils
$errstr = str_replace(ROOT, '', $errstr);
$errfile = str_replace(ROOT, '', $errfile);
// Attempt to log the error to the database
if (DBv2::$db !== null) {
// Encode backtrace data
$backtrace = base64_encode(json_encode(debug_backtrace()));
// Check if this error has already been logged in the past
$past = DBv2::prepare('SELECT * FROM `{prefix}error_log` WHERE `error_backtrace` = :bc OR (`error_string` = :str AND `error_line` = :li)');
$past->execute([
'bc' => $backtrace,
'str' => $errstr,
'li' => $errline,
]);
$past = $past->fetch();
if ($past) {
// If so assign the errid
$errid = $past->error_id;
} else {
// Create an error ID
$errid = substr(md5(microtime()), rand(0, 22), 10);
// Log the error
DBv2::prepare('INSERT INTO `{prefix}error_log` (`error_id`, `error_timestamp`, `error_revision`, `error_type`, `error_line`, `error_string`, `error_file`, `error_backtrace`) VALUES (:id, :time, :rev, :type, :line, :string, :file, :bc)')
->execute([
'id' => $errid,
'time' => date("r"),
'rev' => SAKURA_VERSION,
'type' => $errno,
'line' => $errline,
'string' => $errstr,
'file' => $errfile,
'bc' => $backtrace,
]);
}
}
switch ($errno) {
case E_ERROR:
case E_USER_ERROR:
@ -121,11 +56,6 @@ class Utils
ob_clean();
ob_end_clean();
// Check if this request was made through the ajax thing
if (isset($_REQUEST['ajax'])) {
die('An error occurred while executing the script.|1|javascript:alert("' . (isset($errid) ? 'Error Log ID: '. $errid : 'Failed to log.') . '");');
}
// Check for dev mode
$detailed = Config::local('dev', 'show_errors');
@ -176,7 +106,7 @@ class Utils
<pre class="error">' . $error . '</pre>
<h2>Backtraces</h2>';
foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $num => $trace) {
foreach (debug_backtrace() as $num => $trace) {
$errorPage .= '<h3>#' . $num . '</h3><pre class="error">';
foreach ($trace as $key => $val) {

View file

@ -53,11 +53,9 @@ if (isset($_REQUEST['mode'])) {
// Add page specific things
$renderData['page'] = [
'redirect' => $urls->format('SITE_HOME'),
'message' => 'You are already authenticated. Redirecting...',
'success' => 1,
];
}
}
@ -84,7 +82,6 @@ if (isset($_REQUEST['mode'])) {
// Array containing "human understandable" messages
$messages = [
'INVALID_VERK' => 'The verification key supplied was invalid!',
'INVALID_CODE' => 'Invalid verification key, if you think this is an error contact the administrator.',
'INVALID_USER' => 'The used verification key is not designated for this user.',
@ -92,7 +89,6 @@ if (isset($_REQUEST['mode'])) {
'PASS_TOO_SHIT' => 'Your password is too weak, try adding some special characters.',
'PASS_NOT_MATCH' => 'Passwords do not match.',
'SUCCESS' => 'Successfully changed your password, you may now log in.',
];
// Add page specific things
@ -114,22 +110,18 @@ if (isset($_REQUEST['mode'])) {
// Array containing "human understandable" messages
$messages = [
'USER_NOT_EXIST' => 'The user you tried to activate does not exist.',
'USER_ALREADY_ACTIVE' => 'The user you tried to activate is already active.',
'INVALID_CODE' => 'Invalid activation code, if you think this is an error contact the administrator.',
'INVALID_USER' => 'The used activation code is not designated for this user.',
'SUCCESS' => 'Successfully activated your account, you may now log in.',
];
// Add page specific things
$renderData['page'] = [
'redirect' => $urls->format('SITE_LOGIN'),
'message' => $messages[$activate[1]],
'success' => $activate[0],
];
break;
@ -140,21 +132,17 @@ if (isset($_REQUEST['mode'])) {
// Array containing "human understandable" messages
$messages = [
'AUTH_LOCKED' => 'Authentication is currently not allowed, try again later.',
'USER_NOT_EXIST' => 'The user you tried to activate does not exist (confirm the username/email combination).',
'USER_ALREADY_ACTIVE' => 'The user you tried to activate is already active.',
'SUCCESS' => 'The activation e-mail has been sent to the address associated with your account.',
];
// Add page specific things
$renderData['page'] = [
'redirect' => $urls->format('SITE_HOME'),
'message' => $messages[$resend[1]],
'success' => $resend[0],
];
break;
@ -170,46 +158,11 @@ if (isset($_REQUEST['mode'])) {
// Registration processing
case 'register':
// Attempt registration
$register = Users::register(
$_REQUEST['username'],
$_REQUEST['password'],
$_REQUEST['confirmpassword'],
$_REQUEST['email'],
isset($_REQUEST['tos']),
(
Config::get('recaptcha') ?
$_REQUEST['g-recaptcha-response'] :
null
)
);
// Array containing "human understandable" messages
$messages = [
'AUTH_LOCKED' => 'Authentication is currently not allowed, try again later.',
'DISABLED' => 'Registration is currently disabled.',
'INVALID_REG_KEY' => 'The given registration code was invalid.',
'TOS' => 'You are required to agree to the Terms of Service.',
'CAPTCHA_FAIL' => 'Captcha verification failed, please try again.',
'USER_EXISTS' => 'A user with this username already exists, if you lost your password try using the Lost Password form.',
'NAME_TOO_SHORT' => 'Your name must be at least 3 characters long.',
'NAME_TOO_LONG' => 'Your name can\'t be longer than 16 characters.',
'PASS_TOO_SHIT' => 'Your password is too weak, try adding some special characters.',
'PASS_NOT_MATCH' => 'Passwords do not match.',
'EMAIL_EXISTS' => 'Someone already registered using this email!', // HOW DID I MISS THIS?!
'INVALID_EMAIL' => 'Your e-mail address is formatted incorrectly.',
'INVALID_MX' => 'No valid MX-Record found on the e-mail address you supplied.',
'EMAILSENT' => 'Your registration went through! An activation e-mail has been sent.',
'SUCCESS' => 'Your registration went through! Welcome to ' . Config::get('sitename') . '!',
];
// Add page specific things
$renderData['page'] = [
'redirect' => ($register[0] ? $urls->format('SITE_LOGIN') : $urls->format('SITE_REGISTER')),
'message' => $messages[$register[1]],
'success' => $register[0],
'redirect' => Router::route('auth.register'),
'message' => 'Wrong registration page.',
'success' => 0,
];
break;
@ -220,21 +173,17 @@ if (isset($_REQUEST['mode'])) {
// Array containing "human understandable" messages
$messages = [
'AUTH_LOCKED' => 'Authentication is currently not allowed, try again later.',
'USER_NOT_EXIST' => 'The requested user does not exist (confirm the username/email combination).',
'NOT_ALLOWED' => 'Your account does not have the required permissions to change your password.',
'SUCCESS' => 'The password reset e-mail has been sent to the address associated with your account.',
];
// Add page specific things
$renderData['page'] = [
'redirect' => $urls->format('SITE_FORGOT_PASSWORD'),
'message' => $messages[$passforgot[1]],
'success' => $passforgot[0],
];
break;
@ -255,24 +204,15 @@ if (isset($_REQUEST['mode'])) {
// Add page specific things
$renderData['auth'] = [
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('SITE_HOME'),
'blockRegister' => [
'do' => false,
],
];
// Check if the user is already logged in
if (Users::checkLogin()) {
// Add page specific things
$renderData['page'] = [
'redirect' => $urls->format('SITE_HOME'),
'message' => 'You are already logged in, log out to access this page.',
];
Template::vars($renderData);
@ -280,16 +220,6 @@ if (Users::checkLogin()) {
exit;
}
// Check if a user has already registered from the current IP address
if (count($regUserIP = Users::getUsersByIP(Net::pton(Net::IP())))) {
$renderData['auth']['blockRegister'] = [
'do' => true,
'username' => $regUserIP[array_rand($regUserIP)]['username'],
];
}
// If password forgot things are set display password forget thing
if (isset($_REQUEST['pw']) && $_REQUEST['pw']) {
$renderData['auth']['changingPass'] = true;

View file

@ -411,7 +411,7 @@ a.default:active {
}
#headerLoginForm {
.headerLoginContainer {
background: rgba(211, 191, 255, .8);
border: 1px solid #9475B2;
box-shadow: 0 0 3px #8364A1;
@ -422,14 +422,15 @@ a.default:active {
border-radius: 3px;
}
#headerLoginForm > div {
.headerLoginContainer form,
.headerLoginContainer div {
display: inline-block;
}
#headerLoginForm input[type="submit"],
#headerLoginForm input[type="button"] {
display: inline-block;
border-radius: 3px;
.headerLoginContainer input[type="submit"],
.headerLoginContainer button {
display: inline-block !important;
border-radius: 3px !important;
}
@media (max-width: 640px) {

View file

@ -16,6 +16,8 @@ Router::get('/p/{id}', 'MetaController@infoPage', 'main.infopage');
Router::get('/login', 'AuthController@loginGet', 'auth.login');
Router::post('/login', 'AuthController@loginPost', 'auth.login');
Router::get('/logout', 'AuthController@logout', 'auth.logout');
Router::get('/register', 'AuthController@registerGet', 'auth.register');
Router::post('/register', 'AuthController@registerPost', 'auth.register');
// News
Router::get('/news', 'MetaController@news', 'news.index');

View file

@ -8,7 +8,7 @@
namespace Sakura;
// Define Sakura version
define('SAKURA_VERSION', '20160227');
define('SAKURA_VERSION', '20160228');
// Define Sakura Path
define('ROOT', __DIR__ . '/');

View file

@ -101,7 +101,7 @@
{% if sakura.lockAuth %}
<div class="menu-item fa-lock" style="padding-left: 10px; padding-right: 10px;" title="Authentication is locked"></div>
{% else %}
<a class="menu-item fa-magic" href="{{ urls.format('SITE_REGISTER') }}" title="Login"></a>
<a class="menu-item fa-magic" href="{{ route('auth.register') }}" title="Login"></a>
<a class="menu-item fa-sign-in" href="{{ route('auth.login') }}" title="Login"></a>
{% endif %}
{% endif %}
@ -114,6 +114,7 @@
<div id="userBackground" style="background-image: url('{{ urls.format('IMAGE_BACKGROUND', [(php.self == '/profile.php' ? profile : user).id]) }}');"></div>
{% endif %}
{% if not session.checkLogin and sakura.currentPage != route('auth.login') %}
<div class="headerLoginContainer">
<form method="post" action="{{ route('auth.login') }}" id="headerLoginForm">
<input type="hidden" name="redirect" value="{{ sakura.currentPage }}" />
<input type="hidden" name="session" value="{{ php.sessionid }}" />
@ -135,6 +136,10 @@
<input type="submit" id="headerLoginButton" name="submit" class="inputStyling small" value="Login" />
</div>
</form>
<form method="get" action="{{ route('auth.register') }}">
<button class="inputStyling small">Register</button>
</form>
</div>
{% endif %}
{% if user.permission(constant('Sakura\\Perms\\Site::RESTRICTED')) %}
<div class="headerNotify" style="background: repeating-linear-gradient(-45deg, #B33, #B33 10px, #B00 10px, #B00 20px); color: #FFF; border: 1px solid #C00; box-shadow: 0 0 3px #C00;">

View file

@ -35,86 +35,6 @@
</div>
</form>
</div>
<div class="registerForm">
<div class="head">
Register on {{ sakura.siteName }}
</div>
{% if not sakura.disableRegistration %}
<form id="registerForm" method="post" action="{{ urls.format('AUTH_ACTION') }}" style="display:{% if auth.blockRegister.do %}none{% else %}block{% endif %};">
<input type="hidden" name="mode" value="register" />
<input type="hidden" name="session" value="{{ php.sessionid }}" />
<input type="hidden" name="time" value="{{ php.time }}" />
<div class="leftAlign">
<label for="registerUserName">Username:</label>
</div>
<div class="centreAlign">
<input class="inputStyling" type="text" id="registerUserName" name="username" onkeyup="registerVarCheck(this.id, 'username');" placeholder="Any character" />
</div>
<div class="leftAlign">
<label for="registerEmail">E-mail:</label>
</div>
<div class="centreAlign">
<input class="inputStyling" type="text" id="registerEmail" name="email" onkeyup="registerVarCheck(this.id, 'email');" placeholder="Used for e.g. password retrieval" />
</div>
<div class="leftAlign">
<label for="registerPassword">Password:</label>
</div>
<div class="centreAlign">
<input class="inputStyling" type="password" id="registerPassword" name="password" onkeyup="registerVarCheck(this.id, 'password');" placeholder="Using special characters is recommended" />
</div>
<div class="leftAlign">
<label for="registerConfirmPassword">Confirm Password:</label>
</div>
<div class="centreAlign">
<input class="inputStyling" type="password" id="registerConfirmPassword" name="confirmpassword" onkeyup="registerVarCheck(this.id, 'confirmpw', 'registerPassword');" placeholder="Just to make sure" />
</div>
{% if sakura.requireRegCodes %}
<div class="leftAlign">
<label for="registerCode">Registration Code:</label>
</div>
<div class="centreAlign">
<input class="inputStyling" type="text" id="registerCode" name="registercode" placeholder="Ask another member for one" />
</div>
{% endif %}
{% if sakura.recaptchaEnabled %}
<div class="leftAlign">
<label for="recaptcha_response_field">Verification:</label>
</div>
<div class="centreAlign">
{% include 'elements/captcha.twig' %}
</div>
{% endif %}
<div class="subLinks centreAlign">
<input class="inputStyling" name="tos" type="checkbox" class="ignore-css" id="registerToS" /><label for="registerToS">I agree to the <a class="default" href="{{ urls.format('INFO_PAGE', ['terms']) }}" target="_blank">Terms of Service</a>.
</div>
<div class="centreAlign">
<input class="inputStyling" type="submit" name="submit" value="Register" id="registerAccBtn" />
</div>
</form>
{% if auth.blockRegister.do %}
<div class="registerForm" id="registerWarn" style="display: block;">
<div class="centreAlign">
<div class="fa fa-warning fa-5x" style="display: block; margin: 10px 0 0;"></div>
<h1>Are you {{ auth.blockRegister.username }}?</h1>
<p>Making more than one account is not permitted.</p>
<p>If you lost your password please use the form on the bottom left but if you don't already have an account you can go ahead and click the link below to show the registration form this check is based on your IP so in some cases someone may have registered/used the site on this IP already.</p>
<p>If we find out that you already have an account we may question you about it, if you can give a good reason we'll let it slide otherwise we may issue a temporary ban.</p>
</div>
<div class="subLinks centreAlign">
<a href="javascript:void(0);" class="default" onclick="document.getElementById('registerWarn').style.display='none'; document.getElementById('registerForm').style.display='block';">Register anyway</a>.
</div>
</div>
{% endif %}
{% else %}
<div class="registerForm" id="registerWarn" style="display: block;">
<div class="centreAlign">
<div class="fa fa-remove fa-5x" style="display: block; margin: 10px 0 0;"></div>
<h1>Registration is disabled.</h1>
<p>Please try again later.</p>
</div>
</div>
{% endif %}
</div>
{% if sakura.requireActivation %}
<div class="resendForm">
<div class="head">

View file

@ -14,8 +14,6 @@
<form method="post" action="{{ route('auth.login') }}" id="loginForm">
<input type="hidden" name="redirect" value="{{ sakura.referrer ? sakura.referrer : route('main.index') }}" />
<input type="hidden" name="session" value="{{ php.sessionid }}" />
<input type="hidden" name="time" value="{{ php.time }}" />
<input type="hidden" name="mode" value="login" />
<div class="leftAlign">
<label for="loginUserName">Username:</label>
</div>

View file

@ -0,0 +1,72 @@
{% extends 'global/master.twig' %}
{% block title %}Register{% endblock %}
{% block content %}
{% if sakura.lockAuth or sakura.disableRegistration %}
<div class="loginPage">
<div class="registerForm" id="registerWarn" style="display: block;">
<div class="centreAlign">
<div class="fa fa-remove fa-5x" style="display: block; margin: 10px 0 0;"></div>
<h1>Registration is disabled.</h1>
<p>Please try again later.</p>
</div>
</div>
</div>
{% else %}
<div class="loginPage">
<div class="registerForm">
<div class="head">
Register
</div>
<form id="registerForm" method="post" action="{{ route('auth.register') }}" style="display:{% if haltRegistration %}none{% else %}block{% endif %};">
<input type="hidden" name="session" value="{{ php.sessionid }}" />
<div class="leftAlign">
<label for="registerUserName">Username:</label>
</div>
<div class="centreAlign">
<input class="inputStyling" type="text" id="registerUserName" name="username" onkeyup="registerVarCheck(this.id, 'username');" placeholder="Any character"{% if get.username %} value="{{ get.username }}"{% endif %} />
</div>
<div class="leftAlign">
<label for="registerEmail">E-mail:</label>
</div>
<div class="centreAlign">
<input class="inputStyling" type="text" id="registerEmail" name="email" onkeyup="registerVarCheck(this.id, 'email');" placeholder="Used for e.g. password retrieval"{% if get.email %} value="{{ get.email }}"{% endif %} />
</div>
<div class="leftAlign">
<label for="registerPassword">Password:</label>
</div>
<div class="centreAlign">
<input class="inputStyling" type="password" id="registerPassword" name="password" onkeyup="registerVarCheck(this.id, 'password');" placeholder="Using special characters is recommended" />
</div>
{% if sakura.recaptchaEnabled %}
<div class="leftAlign">
<label for="recaptcha_response_field">Verification:</label>
</div>
<div class="centreAlign">
{% include 'elements/captcha.twig' %}
</div>
{% endif %}
<div class="subLinks centreAlign">
<input class="inputStyling" name="tos" type="checkbox" id="registerToS" /><label for="registerToS">I agree to the <a class="default" href="{{ route('main.infopage', 'terms') }}" target="_blank">Terms of Service</a>.
</div>
<div class="centreAlign">
<input class="inputStyling" type="submit" name="submit" value="Register" id="registerAccBtn" />
</div>
</form>
<div class="registerForm" id="registerWarn" style="display: {% if not haltRegistration %}none{% else %}block{% endif %};">
<div class="centreAlign">
<h1 class="fa fa-warning fa-5x stylised" style="display: block; margin: 10px 0 0;"></h1>
<h1>Are you {{ haltName }}?</h1>
<p>Making more than one account is not permitted.</p>
<p>If you lost your password please use the reset password form but if you don't already have an account you can go ahead and click the link below to show the registration form this check is based on your IP so in some cases someone may have registered/used the site on this IP already.</p>
<p>If we find out that you already have an account we may question you about it, if you can give a good reason we'll let it slide otherwise we may issue a temporary ban.</p>
</div>
<div class="subLinks centreAlign">
<a href="javascript:void(0);" class="default" onclick="document.getElementById('registerWarn').style.display='none'; document.getElementById('registerForm').style.display='block';">This is a mistake, let me register anyway!</a>
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}