r20160228
This commit is contained in:
parent
03ba7e9ffe
commit
370e38a9ff
13 changed files with 366 additions and 482 deletions
|
@ -79,6 +79,7 @@ class AuthController extends Controller
|
||||||
if (Config::get('lock_authentication')) {
|
if (Config::get('lock_authentication')) {
|
||||||
$message = 'Logging in is disabled for security checkups! Try again later.';
|
$message = 'Logging in is disabled for security checkups! Try again later.';
|
||||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||||
|
|
||||||
return Template::render('global/information');
|
return Template::render('global/information');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +98,7 @@ class AuthController extends Controller
|
||||||
if ($rates > 4) {
|
if ($rates > 4) {
|
||||||
$message = 'Your have hit the login rate limit, try again later.';
|
$message = 'Your have hit the login rate limit, try again later.';
|
||||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||||
|
|
||||||
return Template::render('global/information');
|
return Template::render('global/information');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +110,7 @@ class AuthController extends Controller
|
||||||
$this->touchRateLimit($user->id);
|
$this->touchRateLimit($user->id);
|
||||||
$message = 'The user you tried to log into does not exist.';
|
$message = 'The user you tried to log into does not exist.';
|
||||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||||
|
|
||||||
return Template::render('global/information');
|
return Template::render('global/information');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +121,7 @@ class AuthController extends Controller
|
||||||
$this->touchRateLimit($user->id);
|
$this->touchRateLimit($user->id);
|
||||||
$message = 'Logging into this account is disabled.';
|
$message = 'Logging into this account is disabled.';
|
||||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||||
|
|
||||||
return Template::render('global/information');
|
return Template::render('global/information');
|
||||||
|
|
||||||
// Default hashing method
|
// Default hashing method
|
||||||
|
@ -131,6 +135,7 @@ class AuthController extends Controller
|
||||||
$this->touchRateLimit($user->id);
|
$this->touchRateLimit($user->id);
|
||||||
$message = 'The password you entered was invalid.';
|
$message = 'The password you entered was invalid.';
|
||||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||||
|
|
||||||
return Template::render('global/information');
|
return Template::render('global/information');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,6 +145,7 @@ class AuthController extends Controller
|
||||||
$this->touchRateLimit($user->id);
|
$this->touchRateLimit($user->id);
|
||||||
$message = 'Your account does not have the required permissions to log in.';
|
$message = 'Your account does not have the required permissions to log in.';
|
||||||
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
Template::vars(['page' => ['success' => $success, 'redirect' => $redirect, 'message' => $message]]);
|
||||||
|
|
||||||
return Template::render('global/information');
|
return Template::render('global/information');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,4 +181,179 @@ class AuthController extends Controller
|
||||||
|
|
||||||
return Template::render('global/information');
|
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');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,4 +210,30 @@ class Net
|
||||||
// Compare them
|
// Compare them
|
||||||
return ($ip & $mask) === $net;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,7 +166,7 @@ class User
|
||||||
public $background = 0;
|
public $background = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The FIle id of the user's header.
|
* The File id of the user's header.
|
||||||
* @var mixed
|
* @var mixed
|
||||||
*/
|
*/
|
||||||
public $header = 0;
|
public $header = 0;
|
||||||
|
@ -257,26 +257,23 @@ class User
|
||||||
$emailClean = Utils::cleanString($email, true);
|
$emailClean = Utils::cleanString($email, true);
|
||||||
$password = Hashing::createHash($password);
|
$password = Hashing::createHash($password);
|
||||||
|
|
||||||
// Insert the user into the database
|
// Insert the user into the database and get the id
|
||||||
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)')
|
$userId = DB::table('users')
|
||||||
->execute([
|
->insertGetId([
|
||||||
'uname' => $username,
|
'username' => $username,
|
||||||
'uname_clean' => $usernameClean,
|
'username_clean' => $usernameClean,
|
||||||
'pw_hash' => $password[3],
|
'password_hash' => $password[3],
|
||||||
'pw_salt' => $password[2],
|
'password_salt' => $password[2],
|
||||||
'pw_algo' => $password[0],
|
'password_algo' => $password[0],
|
||||||
'pw_iter' => $password[1],
|
'password_iter' => $password[1],
|
||||||
'email' => $emailClean,
|
'email' => $emailClean,
|
||||||
'rank' => 0,
|
'rank_main' => 0,
|
||||||
'r_ip' => Net::pton(Net::IP()),
|
'register_ip' => Net::pton(Net::IP()),
|
||||||
'l_ip' => Net::pton(Net::IP()),
|
'last_ip' => Net::pton(Net::IP()),
|
||||||
'registered' => time(),
|
'user_registered' => time(),
|
||||||
'l_online' => 0,
|
'user_last_online' => 0,
|
||||||
'country' => Utils::getCountryCode(),
|
'user_country' => Utils::getCountryCode(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Get the last id
|
|
||||||
$userId = DBv2::lastID();
|
|
||||||
|
|
||||||
// Create a user object
|
// Create a user object
|
||||||
$user = self::construct($userId);
|
$user = self::construct($userId);
|
||||||
|
@ -294,20 +291,19 @@ class User
|
||||||
/**
|
/**
|
||||||
* The actual constructor
|
* 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
|
// Get the user database row
|
||||||
$userRow = DBv2::prepare('SELECT * FROM `{prefix}users` WHERE `user_id` = :id OR `username_clean` = :clean');
|
$userRow = DB::table('users')
|
||||||
$userRow->execute([
|
->where('user_id', $userId)
|
||||||
'id' => $uid,
|
->orWhere('username_clean', Utils::cleanString($userId, true, true))
|
||||||
'clean' => Utils::cleanString($uid, true, true),
|
->get();
|
||||||
]);
|
|
||||||
$userRow = $userRow->fetch();
|
|
||||||
|
|
||||||
// Populate the variables
|
// Populate the variables
|
||||||
if ($userRow) {
|
if ($userRow) {
|
||||||
|
$userRow = $userRow[0];
|
||||||
$this->id = $userRow->user_id;
|
$this->id = $userRow->user_id;
|
||||||
$this->username = $userRow->username;
|
$this->username = $userRow->username;
|
||||||
$this->usernameClean = $userRow->username_clean;
|
$this->usernameClean = $userRow->username_clean;
|
||||||
|
@ -319,8 +315,8 @@ class User
|
||||||
$this->email = $userRow->email;
|
$this->email = $userRow->email;
|
||||||
$this->mainRankId = $userRow->rank_main;
|
$this->mainRankId = $userRow->rank_main;
|
||||||
$this->colour = $userRow->user_colour;
|
$this->colour = $userRow->user_colour;
|
||||||
$this->registerIp = $userRow->register_ip;
|
$this->registerIp = Net::ntop($userRow->register_ip);
|
||||||
$this->lastIp = $userRow->last_ip;
|
$this->lastIp = Net::ntop($userRow->last_ip);
|
||||||
$this->title = $userRow->user_title;
|
$this->title = $userRow->user_title;
|
||||||
$this->registered = $userRow->user_registered;
|
$this->registered = $userRow->user_registered;
|
||||||
$this->lastOnline = $userRow->user_last_online;
|
$this->lastOnline = $userRow->user_last_online;
|
||||||
|
@ -334,11 +330,9 @@ class User
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all ranks
|
// Get all ranks
|
||||||
$ranks = DBv2::prepare('SELECT * FROM `{prefix}user_ranks` WHERE `user_id` = :id');
|
$ranks = DB::table('user_ranks')
|
||||||
$ranks->execute([
|
->where('user_id', $this->id)
|
||||||
'id' => $this->id,
|
->get(['rank_id']);
|
||||||
]);
|
|
||||||
$ranks = $ranks->fetchAll();
|
|
||||||
|
|
||||||
// Get the rows for all the ranks
|
// Get the rows for all the ranks
|
||||||
foreach ($ranks as $rank) {
|
foreach ($ranks as $rank) {
|
||||||
|
@ -371,15 +365,6 @@ class User
|
||||||
$this->permissions = new Perms(Perms::SITE);
|
$this->permissions = new Perms(Perms::SITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Commit changed to database, doesn't do anything yet.
|
|
||||||
*/
|
|
||||||
public function update()
|
|
||||||
{
|
|
||||||
// placeholder
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the user's birthday.
|
* Get the user's birthday.
|
||||||
*
|
*
|
||||||
|
@ -425,14 +410,13 @@ class User
|
||||||
*/
|
*/
|
||||||
public function isOnline()
|
public function isOnline()
|
||||||
{
|
{
|
||||||
// Get all sessions
|
// Count sessions
|
||||||
$sessions = DBv2::prepare('SELECT `user_id` FROM `{prefix}sessions` WHERE `user_id` = :id');
|
$sessions = DB::table('sessions')
|
||||||
$sessions->execute([
|
->where('user_id', $this->id)
|
||||||
'id' => $this->id,
|
->count();
|
||||||
]);
|
|
||||||
|
|
||||||
// If there's no entries just straight up return false
|
// If there's no entries just straight up return false
|
||||||
if (!$sessions->rowCount()) {
|
if (!$sessions) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,19 +431,20 @@ class User
|
||||||
*/
|
*/
|
||||||
public function forumStats()
|
public function forumStats()
|
||||||
{
|
{
|
||||||
$posts = DBv2::prepare('SELECT * FROM `{prefix}posts` WHERE `poster_id` = :id');
|
$posts = DB::table('posts')
|
||||||
$posts->execute([
|
->where('poster_id', $this->id)
|
||||||
'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 = DB::table('posts')
|
||||||
$threads->execute([
|
->where('poster_id', $this->id)
|
||||||
'id' => $this->id,
|
->distinct()
|
||||||
]);
|
->groupBy('topic_id')
|
||||||
|
->orderBy('post_time')
|
||||||
|
->count();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'posts' => $posts->rowCount(),
|
'posts' => $posts,
|
||||||
'topics' => $threads->rowCount(),
|
'topics' => $threads,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,11 +467,11 @@ class User
|
||||||
|
|
||||||
// Save to the database
|
// Save to the database
|
||||||
foreach ($ranks as $rank) {
|
foreach ($ranks as $rank) {
|
||||||
DBv2::prepare('INSERT INTO `{prefix}ranks` (`rank_id`, `user_id`) VALUES (:rank, :user)')
|
DB::table('user_ranks')
|
||||||
->execute([
|
->insert([
|
||||||
'rank' => $rank,
|
'rank_id' => $rank,
|
||||||
'user' => $this->id,
|
'user_id' => $this->id,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,11 +487,10 @@ class User
|
||||||
|
|
||||||
// Iterate over the ranks
|
// Iterate over the ranks
|
||||||
foreach ($remove as $rank) {
|
foreach ($remove as $rank) {
|
||||||
DBv2::prepare('DELETE FROM `{prefix}user_ranks` WHERE `user_id` = :user AND `rank_id` = :rank')
|
DB::table('ranks')
|
||||||
->execute([
|
->where('user_id', $this->id)
|
||||||
'user' => $this->id,
|
->where('rank_id', $rank)
|
||||||
'rank' => $rank,
|
->delete();
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,11 +504,11 @@ class User
|
||||||
public function setMainRank($rank)
|
public function setMainRank($rank)
|
||||||
{
|
{
|
||||||
// If it does exist update their row
|
// If it does exist update their row
|
||||||
DBv2::prepare('UPDATE `{prefix}users` SET `rank_main` = :rank WHERE `user_id` = :id')
|
DB::table('users')
|
||||||
->execute([
|
->where('user_id', $this->id)
|
||||||
'rank' => $rank,
|
->update([
|
||||||
'id' => $this->id,
|
'rank_main' => $rank,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Return true if everything was successful
|
// Return true if everything was successful
|
||||||
return true;
|
return true;
|
||||||
|
@ -579,12 +563,12 @@ class User
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add friend
|
// Add friend
|
||||||
DBv2::prepare('INSERT INTO `{prefix}friends` (`user_id`, `friend_id`, `friend_timestamp`) VALUES (:user, :friend, :time)')
|
DB::table('friends')
|
||||||
->execute([
|
->insert([
|
||||||
'user' => $this->id,
|
'user_id' => $this->id,
|
||||||
'friend' => $uid,
|
'friend_id' => $uid,
|
||||||
'time' => time(),
|
'friend_timestamp' => time(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Return true because yay
|
// Return true because yay
|
||||||
return [1, $user->isFriends($this->id) ? 'FRIENDS' : 'NOT_MUTUAL'];
|
return [1, $user->isFriends($this->id) ? 'FRIENDS' : 'NOT_MUTUAL'];
|
||||||
|
@ -873,7 +857,7 @@ class User
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have additional options as well
|
// Check if we have additional options as well
|
||||||
if (!$field['field_additional']) {
|
if ($field['field_additional'] != null) {
|
||||||
// Decode the json of the additional stuff
|
// Decode the json of the additional stuff
|
||||||
$additional = json_decode($field['field_additional'], true);
|
$additional = json_decode($field['field_additional'], true);
|
||||||
|
|
||||||
|
|
|
@ -98,104 +98,6 @@ class Users
|
||||||
return [$uid, $sid];
|
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
|
* Send password forgot e-mail
|
||||||
*
|
*
|
||||||
|
@ -455,28 +357,6 @@ class Users
|
||||||
return [1, 'SUCCESS'];
|
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.
|
* 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.
|
* Get a user's notifications.
|
||||||
*
|
*
|
||||||
|
|
|
@ -17,35 +17,6 @@ use PHPMailer;
|
||||||
*/
|
*/
|
||||||
class Utils
|
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.
|
* The error handler.
|
||||||
*
|
*
|
||||||
|
@ -60,42 +31,6 @@ class Utils
|
||||||
$errstr = str_replace(ROOT, '', $errstr);
|
$errstr = str_replace(ROOT, '', $errstr);
|
||||||
$errfile = str_replace(ROOT, '', $errfile);
|
$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) {
|
switch ($errno) {
|
||||||
case E_ERROR:
|
case E_ERROR:
|
||||||
case E_USER_ERROR:
|
case E_USER_ERROR:
|
||||||
|
@ -121,11 +56,6 @@ class Utils
|
||||||
ob_clean();
|
ob_clean();
|
||||||
ob_end_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
|
// Check for dev mode
|
||||||
$detailed = Config::local('dev', 'show_errors');
|
$detailed = Config::local('dev', 'show_errors');
|
||||||
|
|
||||||
|
@ -176,7 +106,7 @@ class Utils
|
||||||
<pre class="error">' . $error . '</pre>
|
<pre class="error">' . $error . '</pre>
|
||||||
<h2>Backtraces</h2>';
|
<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">';
|
$errorPage .= '<h3>#' . $num . '</h3><pre class="error">';
|
||||||
|
|
||||||
foreach ($trace as $key => $val) {
|
foreach ($trace as $key => $val) {
|
||||||
|
|
|
@ -53,11 +53,9 @@ if (isset($_REQUEST['mode'])) {
|
||||||
|
|
||||||
// Add page specific things
|
// Add page specific things
|
||||||
$renderData['page'] = [
|
$renderData['page'] = [
|
||||||
|
|
||||||
'redirect' => $urls->format('SITE_HOME'),
|
'redirect' => $urls->format('SITE_HOME'),
|
||||||
'message' => 'You are already authenticated. Redirecting...',
|
'message' => 'You are already authenticated. Redirecting...',
|
||||||
'success' => 1,
|
'success' => 1,
|
||||||
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +82,6 @@ if (isset($_REQUEST['mode'])) {
|
||||||
|
|
||||||
// Array containing "human understandable" messages
|
// Array containing "human understandable" messages
|
||||||
$messages = [
|
$messages = [
|
||||||
|
|
||||||
'INVALID_VERK' => 'The verification key supplied was invalid!',
|
'INVALID_VERK' => 'The verification key supplied was invalid!',
|
||||||
'INVALID_CODE' => 'Invalid verification key, if you think this is an error contact the administrator.',
|
'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.',
|
'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_TOO_SHIT' => 'Your password is too weak, try adding some special characters.',
|
||||||
'PASS_NOT_MATCH' => 'Passwords do not match.',
|
'PASS_NOT_MATCH' => 'Passwords do not match.',
|
||||||
'SUCCESS' => 'Successfully changed your password, you may now log in.',
|
'SUCCESS' => 'Successfully changed your password, you may now log in.',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// Add page specific things
|
// Add page specific things
|
||||||
|
@ -114,22 +110,18 @@ if (isset($_REQUEST['mode'])) {
|
||||||
|
|
||||||
// Array containing "human understandable" messages
|
// Array containing "human understandable" messages
|
||||||
$messages = [
|
$messages = [
|
||||||
|
|
||||||
'USER_NOT_EXIST' => 'The user you tried to activate does not exist.',
|
'USER_NOT_EXIST' => 'The user you tried to activate does not exist.',
|
||||||
'USER_ALREADY_ACTIVE' => 'The user you tried to activate is already active.',
|
'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_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.',
|
'INVALID_USER' => 'The used activation code is not designated for this user.',
|
||||||
'SUCCESS' => 'Successfully activated your account, you may now log in.',
|
'SUCCESS' => 'Successfully activated your account, you may now log in.',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// Add page specific things
|
// Add page specific things
|
||||||
$renderData['page'] = [
|
$renderData['page'] = [
|
||||||
|
|
||||||
'redirect' => $urls->format('SITE_LOGIN'),
|
'redirect' => $urls->format('SITE_LOGIN'),
|
||||||
'message' => $messages[$activate[1]],
|
'message' => $messages[$activate[1]],
|
||||||
'success' => $activate[0],
|
'success' => $activate[0],
|
||||||
|
|
||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -140,21 +132,17 @@ if (isset($_REQUEST['mode'])) {
|
||||||
|
|
||||||
// Array containing "human understandable" messages
|
// Array containing "human understandable" messages
|
||||||
$messages = [
|
$messages = [
|
||||||
|
|
||||||
'AUTH_LOCKED' => 'Authentication is currently not allowed, try again later.',
|
'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_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.',
|
'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.',
|
'SUCCESS' => 'The activation e-mail has been sent to the address associated with your account.',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// Add page specific things
|
// Add page specific things
|
||||||
$renderData['page'] = [
|
$renderData['page'] = [
|
||||||
|
|
||||||
'redirect' => $urls->format('SITE_HOME'),
|
'redirect' => $urls->format('SITE_HOME'),
|
||||||
'message' => $messages[$resend[1]],
|
'message' => $messages[$resend[1]],
|
||||||
'success' => $resend[0],
|
'success' => $resend[0],
|
||||||
|
|
||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -170,46 +158,11 @@ if (isset($_REQUEST['mode'])) {
|
||||||
|
|
||||||
// Registration processing
|
// Registration processing
|
||||||
case 'register':
|
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
|
// Add page specific things
|
||||||
$renderData['page'] = [
|
$renderData['page'] = [
|
||||||
|
'redirect' => Router::route('auth.register'),
|
||||||
'redirect' => ($register[0] ? $urls->format('SITE_LOGIN') : $urls->format('SITE_REGISTER')),
|
'message' => 'Wrong registration page.',
|
||||||
'message' => $messages[$register[1]],
|
'success' => 0,
|
||||||
'success' => $register[0],
|
|
||||||
|
|
||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -220,21 +173,17 @@ if (isset($_REQUEST['mode'])) {
|
||||||
|
|
||||||
// Array containing "human understandable" messages
|
// Array containing "human understandable" messages
|
||||||
$messages = [
|
$messages = [
|
||||||
|
|
||||||
'AUTH_LOCKED' => 'Authentication is currently not allowed, try again later.',
|
'AUTH_LOCKED' => 'Authentication is currently not allowed, try again later.',
|
||||||
'USER_NOT_EXIST' => 'The requested user does not exist (confirm the username/email combination).',
|
'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.',
|
'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.',
|
'SUCCESS' => 'The password reset e-mail has been sent to the address associated with your account.',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// Add page specific things
|
// Add page specific things
|
||||||
$renderData['page'] = [
|
$renderData['page'] = [
|
||||||
|
|
||||||
'redirect' => $urls->format('SITE_FORGOT_PASSWORD'),
|
'redirect' => $urls->format('SITE_FORGOT_PASSWORD'),
|
||||||
'message' => $messages[$passforgot[1]],
|
'message' => $messages[$passforgot[1]],
|
||||||
'success' => $passforgot[0],
|
'success' => $passforgot[0],
|
||||||
|
|
||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -255,24 +204,15 @@ if (isset($_REQUEST['mode'])) {
|
||||||
|
|
||||||
// Add page specific things
|
// Add page specific things
|
||||||
$renderData['auth'] = [
|
$renderData['auth'] = [
|
||||||
|
|
||||||
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('SITE_HOME'),
|
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('SITE_HOME'),
|
||||||
'blockRegister' => [
|
|
||||||
|
|
||||||
'do' => false,
|
|
||||||
|
|
||||||
],
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// Check if the user is already logged in
|
// Check if the user is already logged in
|
||||||
if (Users::checkLogin()) {
|
if (Users::checkLogin()) {
|
||||||
// Add page specific things
|
// Add page specific things
|
||||||
$renderData['page'] = [
|
$renderData['page'] = [
|
||||||
|
|
||||||
'redirect' => $urls->format('SITE_HOME'),
|
'redirect' => $urls->format('SITE_HOME'),
|
||||||
'message' => 'You are already logged in, log out to access this page.',
|
'message' => 'You are already logged in, log out to access this page.',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
Template::vars($renderData);
|
Template::vars($renderData);
|
||||||
|
@ -280,16 +220,6 @@ if (Users::checkLogin()) {
|
||||||
exit;
|
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 password forgot things are set display password forget thing
|
||||||
if (isset($_REQUEST['pw']) && $_REQUEST['pw']) {
|
if (isset($_REQUEST['pw']) && $_REQUEST['pw']) {
|
||||||
$renderData['auth']['changingPass'] = true;
|
$renderData['auth']['changingPass'] = true;
|
||||||
|
|
|
@ -411,7 +411,7 @@ a.default:active {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#headerLoginForm {
|
.headerLoginContainer {
|
||||||
background: rgba(211, 191, 255, .8);
|
background: rgba(211, 191, 255, .8);
|
||||||
border: 1px solid #9475B2;
|
border: 1px solid #9475B2;
|
||||||
box-shadow: 0 0 3px #8364A1;
|
box-shadow: 0 0 3px #8364A1;
|
||||||
|
@ -422,14 +422,15 @@ a.default:active {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#headerLoginForm > div {
|
.headerLoginContainer form,
|
||||||
|
.headerLoginContainer div {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
#headerLoginForm input[type="submit"],
|
.headerLoginContainer input[type="submit"],
|
||||||
#headerLoginForm input[type="button"] {
|
.headerLoginContainer button {
|
||||||
display: inline-block;
|
display: inline-block !important;
|
||||||
border-radius: 3px;
|
border-radius: 3px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
|
|
|
@ -16,6 +16,8 @@ Router::get('/p/{id}', 'MetaController@infoPage', 'main.infopage');
|
||||||
Router::get('/login', 'AuthController@loginGet', 'auth.login');
|
Router::get('/login', 'AuthController@loginGet', 'auth.login');
|
||||||
Router::post('/login', 'AuthController@loginPost', 'auth.login');
|
Router::post('/login', 'AuthController@loginPost', 'auth.login');
|
||||||
Router::get('/logout', 'AuthController@logout', 'auth.logout');
|
Router::get('/logout', 'AuthController@logout', 'auth.logout');
|
||||||
|
Router::get('/register', 'AuthController@registerGet', 'auth.register');
|
||||||
|
Router::post('/register', 'AuthController@registerPost', 'auth.register');
|
||||||
|
|
||||||
// News
|
// News
|
||||||
Router::get('/news', 'MetaController@news', 'news.index');
|
Router::get('/news', 'MetaController@news', 'news.index');
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
namespace Sakura;
|
namespace Sakura;
|
||||||
|
|
||||||
// Define Sakura version
|
// Define Sakura version
|
||||||
define('SAKURA_VERSION', '20160227');
|
define('SAKURA_VERSION', '20160228');
|
||||||
|
|
||||||
// Define Sakura Path
|
// Define Sakura Path
|
||||||
define('ROOT', __DIR__ . '/');
|
define('ROOT', __DIR__ . '/');
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
{% if sakura.lockAuth %}
|
{% if sakura.lockAuth %}
|
||||||
<div class="menu-item fa-lock" style="padding-left: 10px; padding-right: 10px;" title="Authentication is locked"></div>
|
<div class="menu-item fa-lock" style="padding-left: 10px; padding-right: 10px;" title="Authentication is locked"></div>
|
||||||
{% else %}
|
{% 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>
|
<a class="menu-item fa-sign-in" href="{{ route('auth.login') }}" title="Login"></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% 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>
|
<div id="userBackground" style="background-image: url('{{ urls.format('IMAGE_BACKGROUND', [(php.self == '/profile.php' ? profile : user).id]) }}');"></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not session.checkLogin and sakura.currentPage != route('auth.login') %}
|
{% if not session.checkLogin and sakura.currentPage != route('auth.login') %}
|
||||||
|
<div class="headerLoginContainer">
|
||||||
<form method="post" action="{{ route('auth.login') }}" id="headerLoginForm">
|
<form method="post" action="{{ route('auth.login') }}" id="headerLoginForm">
|
||||||
<input type="hidden" name="redirect" value="{{ sakura.currentPage }}" />
|
<input type="hidden" name="redirect" value="{{ sakura.currentPage }}" />
|
||||||
<input type="hidden" name="session" value="{{ php.sessionid }}" />
|
<input type="hidden" name="session" value="{{ php.sessionid }}" />
|
||||||
|
@ -135,6 +136,10 @@
|
||||||
<input type="submit" id="headerLoginButton" name="submit" class="inputStyling small" value="Login" />
|
<input type="submit" id="headerLoginButton" name="submit" class="inputStyling small" value="Login" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<form method="get" action="{{ route('auth.register') }}">
|
||||||
|
<button class="inputStyling small">Register</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.permission(constant('Sakura\\Perms\\Site::RESTRICTED')) %}
|
{% 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;">
|
<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;">
|
||||||
|
|
|
@ -35,86 +35,6 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</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 %}
|
{% if sakura.requireActivation %}
|
||||||
<div class="resendForm">
|
<div class="resendForm">
|
||||||
<div class="head">
|
<div class="head">
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
<form method="post" action="{{ route('auth.login') }}" id="loginForm">
|
<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="redirect" value="{{ sakura.referrer ? sakura.referrer : route('main.index') }}" />
|
||||||
<input type="hidden" name="session" value="{{ php.sessionid }}" />
|
<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">
|
<div class="leftAlign">
|
||||||
<label for="loginUserName">Username:</label>
|
<label for="loginUserName">Username:</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
72
templates/yuuno/main/register.twig
Normal file
72
templates/yuuno/main/register.twig
Normal 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 %}
|
Reference in a new issue