User registrations are almost a thing

This commit is contained in:
Pachira 2015-04-18 18:26:52 +00:00
parent 3b38696c0a
commit 77985e1ab4
10 changed files with 1214 additions and 15 deletions

View file

@ -31,7 +31,10 @@ class Main {
Session::init();
// Templating engine
Templates::init(Configuration::getLocalConfig('etc', 'design'));
Templates::init(Configuration::getConfig('site_style'));
// Assign servers file to whois class
Whois::setServers(Configuration::getLocalConfig('etc', 'whoisservers'));
// Markdown Parser
self::initMD();
@ -74,9 +77,9 @@ class Main {
public static function ErrorHandler($errno, $errstr, $errfile, $errline) {
// Set some variables to work with including A HUGE fallback hackjob for the templates folder
$errstr = str_replace(Configuration::getLocalConfig('etc', 'localPath'), '', $errstr);
$errfile = str_replace(Configuration::getLocalConfig('etc', 'localPath'), '', $errfile);
$templates = (Configuration::getLocalConfig('etc', 'templatesPath') !== null && !empty(Configuration::getLocalConfig('etc', 'templatesPath'))) ? Configuration::getLocalConfig('etc', 'templatesPath') : '/var/www/flashii.net/_sakuya/templates/';
$errstr = str_replace(ROOT, '', $errstr);
$errfile = str_replace(ROOT, '', $errfile);
$templates = ROOT .'_sakura/templates/';
switch ($errno) {
@ -114,6 +117,80 @@ class Main {
}
// Send emails
public static function sendMail($to, $subject, $body) {
// Initialise PHPMailer
$mail = new \PHPMailer();
// Set to SMTP
$mail->IsSMTP();
// Set the SMTP server host
$mail->Host = Configuration::getConfig('smtp_server');
// Do we require authentication?
$mail->SMTPAuth = Configuration::getConfig('smtp_auth');
// Do we encrypt as well?
$mail->SMTPSecure = Configuration::getConfig('smtp_secure');
// Set the port to the SMTP server
$mail->Port = Configuration::getConfig('smtp_port');
// If authentication is required log in as well
if(Configuration::getConfig('smtp_auth')) {
$mail->Username = Configuration::getConfig('smtp_username');
$mail->Password = base64_decode(Configuration::getConfig('smtp_password'));
}
// Add a reply-to header
$mail->AddReplyTo(Configuration::getConfig('smtp_replyto_mail'), Configuration::getConfig('smtp_replyto_name'));
// Set a from address as well
$mail->SetFrom(Configuration::getConfig('smtp_from_email'), Configuration::getConfig('smtp_from_name'));
// Set the addressee
foreach($to as $email => $name)
$mail->AddBCC($email, $name);
// Subject line
$mail->Subject = $subject;
// Set the mail type to HTML
$mail->isHTML(true);
// Set email contents
$htmlMail = file_get_contents(ROOT .'_sakura/templates/htmlEmail.tpl');
// Replace template tags
$htmlMail = str_replace('{{ sitename }}', Configuration::getConfig('sitename'), $htmlMail);
$htmlMail = str_replace('{{ siteurl }}', '//'. Configuration::getLocalConfig('urls', 'main'), $htmlMail);
$htmlMail = str_replace('{{ contents }}', self::mdParse($body), $htmlMail);
// Set HTML body
$mail->Body = $htmlMail;
// Set fallback body
$mail->AltBody = $body;
// Send the message
$send = $mail->Send();
// Clear the addressee list
$mail->ClearAddresses();
// If we got an error return the error
if(!$send)
return $mail->ErrorInfo;
// Else just return whatever
return $send;
}
// Legacy password hashing to be able to validate passwords from users on the old backend.
public static function legacyPasswordHash($data) {
@ -313,4 +390,21 @@ class Main {
}
// Get country code from CloudFlare header (which just returns EU if not found)
public static function getCountryCode() {
// Check if remote IP is a CloudFlare IP
if(self::checkCFIP($_SERVER['REMOTE_ADDR'])) {
// Check if the required header is set and return it
if(isset($_SERVER['HTTP_CF_IPCOUNTRY']))
return $_SERVER['HTTP_CF_IPCOUNTRY'];
}
// Return EU as a fallback
return 'EU';
}
}

View file

@ -19,7 +19,7 @@ class Templates {
self::$_TPL = $template;
// Assign config path to a variable so we don't have to type it out twice
$confPath = Configuration::getLocalConfig('etc', 'templatesPath') .'/'. self::$_TPL .'/template.cfg';
$confPath = ROOT .'_sakura/templates/'. self::$_TPL .'/template.cfg';
// Check if the configuration file exists
if(!file_exists($confPath))
@ -41,7 +41,7 @@ class Templates {
private static function twigLoader() {
// Initialise Twig Filesystem Loader
$twigLoader = new \Twig_Loader_Filesystem(Configuration::getLocalConfig('etc', 'templatesPath') .'/'. Configuration::getLocalConfig('etc', 'design'));
$twigLoader = new \Twig_Loader_Filesystem(ROOT .'_sakura/templates/'. self::$_TPL);
// And now actually initialise the templating engine
self::$_ENG = new \Twig_Environment($twigLoader, array(

View file

@ -14,7 +14,7 @@ class Users {
'username_clean' => 'deleted user',
'password_hash' => '',
'password_salt' => '',
'password_algo' => 'sha256',
'password_algo' => 'nologin',
'password_iter' => 1000,
'password_chan' => 0,
'password_new' => '',
@ -38,7 +38,7 @@ class Users {
// Empty rank template
public static $emptyRank = [
'id' => 0,
'rankname' => 'Non-existent Rank',
'rankname' => 'Non-existent Rank',
'multi' => 0,
'colour' => '#444',
'description' => 'A hardcoded dummy rank for fallback.'
@ -85,7 +85,11 @@ class Users {
$userData = self::getUser($uid);
// Validate password
if($userData['password_algo'] == 'legacy') { // Shitty legacy method of sha512(strrev(sha512()))
if($userData['password_algo'] == 'nologin') { // Disable logging in to an account
return [0, 'NO_LOGIN'];
} elseif($userData['password_algo'] == 'legacy') { // Shitty legacy method of sha512(strrev(sha512()))
if(Main::legacyPasswordHash($password) != $userData['password_hash'])
return [0, 'INCORRECT_PASSWORD'];
@ -138,6 +142,214 @@ class Users {
}
// Register user
public static function register($username, $password, $confirmpass, $email, $tos, $captcha = null, $regkey = null) {
// Check if registration is even enabled
if(Configuration::getConfig('disable_registration'))
return [0, 'DISABLED'];
// Check if registration codes are required
if(Configuration::getConfig('require_registration_code')) {
// Check if the code is valid
if(!self::checkRegistrationCode($regkey))
return [0, 'INVALID_REG_KEY'];
}
// Check if the user agreed to the ToS
if(!$tos)
return [0, 'TOS'];
// Verify the captcha if it's enabled
if(Configuration::getConfig('recaptcha')) {
if(!Main::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) < 3)
return [0, 'NAME_TOO_SHORT'];
// Username too long
if(strlen($username) > 16)
return [0, 'NAME_TOO_LONG'];
// Password too short
if(strlen($password) < 8)
return [0, 'PASS_TOO_SHORT'];
// Password too long
if(strlen($password) > 256)
return [0, 'PASS_TOO_LONG'];
// Passwords do not match
if($password != $confirmpassword)
return [0, 'PASS_NOT_MATCH'];
// 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(!Main::checkMXRecord($email))
return [0, 'INVALID_MX'];
// Set a few variables
$usernameClean = Main::cleanString($username);
$password = Hashing::create_hash($password);
$requireActive = Configuration::getConfig('require_activation');
$userRank = $requireActive ? [0] : [1];
$userRankJson = json_encode($userRank);
// Insert the user into the database
Database::insert('users', [
'username' => $username,
'username_clean' => $usernameClean,
'password_hash' => $password[3],
'password_salt' => $password[2],
'password_algo' => $password[0],
'password_iter' => $password[1],
'email' => $email,
'rank_main' => $userRank[0],
'ranks' => $userRankJson,
'register_ip' => Main::getRemoteIP(),
'last_ip' => Main::getRemoteIP(),
'regdate' => time(),
'lastdate' => 0,
'lastunamechange' => time(),
'country' => Main::getCountryCode(),
'profile_data' => '[]'
]);
// Get userid of the new user
$uid = Database::fetch('users', false, ['username_clean' => [$usernameClean, '=']])['id'];
// Check if we require e-mail activation
if($requireActive) {
// Send activation e-mail to user
self::sendActivationMail($uid);
}
// Check if registration codes are required
if(Configuration::getConfig('require_registration_code')) {
// If we do mark the registration code that was used as used
self::markRegistrationCodeUsed($regkey, $uid);
}
// Return true with a specific message if needed
return [1, ($requireActive ? 'EMAILSENT' : 'SUCCESS')];
}
// Send the activation e-mail and do other required stuff
public static function sendActivationMail($uid) {
// Get the user data
$user = Database::fetch('users', false, ['id' => [$uid, '=']]);
// User is already activated or doesn't even exist
if(!count($user) > 1 || $user['rank_main'])
return false;
// Generate activation key
// $activate = <interface with the shit for the activationkeys table here>;
$activate = 'null';
// Build the e-mail
$message = "Welcome to ". Configuration::getConfig('sitename') ."!\r\n\r\n";
$message .= "Please keep this e-mail for your records. Your account intormation is as follows:\r\n\r\n";
$message .= "----------------------------\r\n\r\n";
$message .= "Username: ". $user['username'] ."\r\n";
$message .= "Your profile: http://". Configuration::getLocalConfig('urls', 'main') ."/u/". $user['id'] ."\r\n\r\n";
$message .= "----------------------------\r\n\r\n";
$message .= "Please visit the following link in order to activate your account:\r\n\r\n";
$message .= "http://". Configuration::getLocalConfig('urls', 'main') ."/activate?mode=activate&u=". $user['id'] ."&k=". $activate ."\r\n\r\n";
$message .= "Your password has been securely stored in our database and cannot be retrieved. ";
$message .= "In the event that it is forgotten, you will be able to reset it using the email address associated with your account.\r\n\r\n";
$message .= "Thank you for registering.\r\n\r\n";
$message .= "--\r\n\r\nSincerely\r\n\r\n". Configuration::getConfig('mail_signature');
// Send the message
Main::sendMail([$user['email'] => $user['username']], Configuration::getConfig('sitename') .' Activation Mail', $message);
// Return true indicating that the things have been sent
return true;
}
// Check if registration code is valid
public static function checkRegistrationCode($code) {
// Get registration key
$keyRow = Database::fetch('regcodes', true, ['code' => [$code, '='], 'key_used' => [0, '=']]);
// Check if it exists and return it
return count($keyRow) ? $keyRow[0]['id'] : false;
}
// Mark registration code as used
public static function markRegistrationCodeUsed($code, $uid = 0) {
// Check if the code exists
if(!$id = self::checkRegistrationCode($code))
return false;
// Mark it as used
Database::update('regcodes', [
[
'used_by' => $uid,
'key_used' => 1
],
[
'id' => [$id, '=']
]
]);
// Return true because yeah
return true;
}
// Create new registration code
public static function createRegistrationCode() {
// Check if we're logged in
if(!self::checkLogin())
return false;
// Check if the user is not exceeding the maximum registration key amount
if(count(Database::fetch('regcodes', true, ['uid' => [Session::$userId, '=']])) >= Configuration::getConfig('max_reg_keys'))
return false;
// Generate a code by MD5'ing some random bullshit
$code = md5('SAKURA'. rand(0, 99999999) . Session::$userId .'NOOKLSISGOD');
// Insert the key into the database
Database::insert('regcodes', [
'code' => $code,
'created_by' => Session::$userId,
'used_by' => 0,
'key_used' => 0
]);
// Return the code
return $code;
}
// Check if a user exists
public static function userExists($user, $id = true) {

View file

@ -0,0 +1,210 @@
<?php
/*
* Whois in PHP (featuring a very original name), adjusted for Sakura
* By Flashwave <http://flash.moe>
* Released under the MIT-License
*
* The MIT License (MIT)
*
* Copyright (c) 2015 Flashwave
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
namespace Sakura;
class Whois {
// Variables
public static $servers;
// Set the whois servers list
public static function setServers($serversFile) {
// Check if the file exists and if it does get contents.
if(file_exists($serversFile))
$servers = file_get_contents($serversFile);
else
trigger_error('Failed to load whois servers file', E_USER_ERROR);
// Parse json
if(($servers = json_decode($servers, true)) != true)
trigger_error('Error while parsing whois servers file JSON', E_USER_ERROR);
// Check for neccesary keys
if(!array_key_exists('tld', $servers) || !array_key_exists('ip', $servers))
trigger_error('One or more of the required whois lists isn\'t set, please check your whois servers file', E_USER_ERROR);
// If everything is gucci set self::$servers
self::$servers = $servers;
}
// Query the whois servers
public static function query($address) {
// Call validate to use the right whois type
switch(self::validateAddress($address)) {
case 1: // validateAddress returns 1 for a domain...
return self::lookupDomain($address);
case 2: // ...and 2 for both IPv4 and IPv6 (should be fine)...
return self::lookupIP($address);
case 0: // ...and 0 in case the type is invalid in which case...
default: // ...a false is returned by this function
return false;
}
}
// Validates an address
private static function validateAddress($address) {
// Check if the given address is an IP address
if(filter_var($address, FILTER_VALIDATE_IP))
return 2;
// Check if given address is a domain name
if(preg_match("/^([-a-z0-9]{2,100})\.([a-z\.]{2,8})$/i", $address))
return 1;
// If unsuccessful return 0
return 0;
}
// Look up a domain
private static function lookupDomain($address) {
// Get list of servers
$servers = self::$servers['tld'];
// Break domain up in parts
$addressParts = explode(".", $address);
// Get TLD
$tld = strtolower(array_pop($addressParts));
// Get proper whois server address
if(!$server = $servers[$tld])
return 'Error: No appropriate whois server found for the TLD '. $tld .', check if the given address is correct.';
// Get results from whois server
if(!$result = self::queryWhois($server, $address)) {
// Return an error if there's no results were retrieved.
return 'Error: No results retrieved from '. $server .' for '. $address .'.';
} else {
// Assign result with heading text to return variable
$return = $address ." domain lookup results from ". $server .":\r\n\r\n". $result;
// Check if there's a secondary whois server
while(strpos($result, "Whois Server:") !== FALSE) {
preg_match("/Whois Server: (.*)/", $return, $matches);
// If there is call it...
if(isset($matches[1])) {
$result = self::queryWhois(($server = $matches[1]), $address);
// ...and append the retrieved values to the return variable
$return .= "\r\n-------------\r\n\r\n". $address ." domain lookup results from ". $server .":\r\n". $result;
}
}
}
// If all is good return the return variable
return $return;
}
// Look up an IP
private static function lookupIP($address) {
// Get list of servers
$servers = self::$servers['ip'];
// Set variable to keep results in
$results = array();
// Query servers
foreach($servers as $server) {
// Get results
$result = self::queryWhois($server, $address);
// Assign result to results array if not in it yet
if($result && !in_array($result, $results))
$results[$server] = $result;
}
// Create variable to keep return value
$return = "RESULTS FOUND: ". count($results);
// Append results
foreach($results as $server => $result) {
$return .= "\r\n\r\n-------------"
. "\r\nLookup results for "
. $address
. " from "
. $server
. " server:\r\n\r\n"
. $result;
}
// Return results
return $return;
}
// Query whois server
private static function queryWhois($server, $address, $port = 43, $timeout = 10) {
// Open socket
$query = @fsockopen($server, $port, $errno, $errstr, $timeout) or trigger_error('Failed to open socket: '. $errno .' - '. $errstr, E_USER_ERROR);
// Send address
fputs($query, $address ."\r\n");
// Await output
$out = null;
while(!feof($query))
$out .= fgets($query);
// Close socket
fclose($query);
// Return results
return $out;
}
}

View file

@ -21,7 +21,5 @@ $sakuraConf['urls']['chat'] = 'chat.flashii.net'; // Chat url
$sakuraConf['urls']['manage'] = 'manage.flashii.net'; // Moderator panel url
// Errata
$sakuraConf['etc']['localPath'] = '/var/www/flashii.net/'; // Local path
$sakuraConf['etc']['templatesPath'] = $sakuraConf['etc']['localPath'] .'_sakura/templates/'; // Path to templates directory
$sakuraConf['etc']['design'] = 'yuuno'; // Style name
$sakuraConf['etc']['cfhosts'] = $sakuraConf['etc']['localPath'] .'_sakura/config/cloudflare.hosts'; // Cloudflare IP subnets file
$sakuraConf['etc']['cfhosts'] = ROOT .'_sakura/config/cloudflare.hosts'; // Cloudflare IP subnets file
$sakuraConf['etc']['whoisservers'] = ROOT .'_sakura/config/whois.json'; // JSON with Whois servers

609
_sakura/config/whois.json Normal file
View file

@ -0,0 +1,609 @@
{
"tld": {
"abogado": "whois.nic.ac",
"ac": "whois.nic.ac",
"academy": "whois.donuts.co",
"accountants": "whois.donuts.co",
"active": "whois.afilias-srs.net",
"actor": "whois.unitedtld.com",
"actor": "whois.unitedtld.com",
"ad": "whois.ripe.net",
"ae": "whois.nic.ae",
"aero": "whois.aero",
"af": "whois.nic.af",
"ag": "whois.nic.ag",
"agency": "whois.donuts.co",
"ai": "whois.ai",
"airforce": "whois.unitedtld.com",
"al": "whois.ripe.net",
"allfinanz": "whois.ksregistry.net",
"alsace": "whois-alsace.nic.fr",
"am": "whois.amnic.net",
"army": "whois.rightside.co",
"arpa": "whois.iana.org",
"as": "whois.nic.as",
"asia": "whois.nic.asia",
"associates": "whois.donuts.co",
"at": "whois.nic.at",
"attorney": "whois.rightside.co",
"au": "whois.audns.net.au",
"auction": "whois.unitedtld.com",
"audio": "whois.uniregistry.net",
"autos": "whois.afilias-srs.net",
"aw": "whois.nic.aw",
"ax": "whois.ax",
"az": "whois.ripe.net",
"band": "whois.rightside.co",
"bar": "whois.nic.bar",
"bargains": "whois.donuts.co",
"bayern": "whois-dub.mm-registry.com",
"be": "whois.dns.be",
"beer": "whois-dub.mm-registry.com",
"berlin": "whois.nic.berlin",
"best": "whois.nic.best",
"bg": "whois.register.bg",
"bi": "whois.nic.bi",
"bike": "whois.donuts.co",
"bio": "whois.ksregistry.net",
"biz": "whois.biz",
"bj": "whois.nic.bj",
"black": "whois.afilias.net",
"blackfriday": "whois.uniregistry.net",
"blue": "whois.afilias.net",
"bmw": "whois.ksregistry.net",
"bn": "whois.bn",
"bnpparibas": "whois.afilias-srs.net",
"bo": "whois.nic.bo",
"boo": "domain-registry-whois.l.google.com",
"boutique": "whois.donuts.co",
"br": "whois.nic.br",
"brussels": "whois.nic.brussels",
"bt": "whois.netnames.net",
"budapest": "whois-dub.mm-registry.com",
"build": "whois.nic.build",
"builders": "whois.donuts.co",
"business": "whois.donuts.co",
"business": "whois.donuts.co",
"bw": "whois.nic.net.bw",
"by": "whois.cctld.by",
"bz": "whois.belizenic.bz",
"bzh": "whois-bzh.nic.fr",
"ca": "whois.cira.ca",
"cab": "whois.donuts.co",
"cal": "domain-registry-whois.l.google.com",
"camera": "whois.donuts.co",
"camp": "whois.donuts.co",
"cancerresearch": "whois.nic.cancerresearch",
"capetown": "capetown-whois.registry.net.za",
"capital": "whois.donuts.co",
"cards": "whois.donuts.co",
"care": "whois.donuts.co",
"career": "whois.nic.career",
"careers": "whois.donuts.co",
"casa": "whois-dub.mm-registry.com",
"cash": "whois.donuts.co",
"cat": "whois.cat",
"catering": "whois.donuts.co",
"cc": "ccwhois.verisign-grs.com",
"cd": "whois.nic.cd",
"center": "whois.donuts.co",
"ceo": "whois.nic.ceo",
"cern": "whois.afilias-srs.net",
"cf": "whois.dot.cf",
"ch": "whois.nic.ch",
"channel": "domain-registry-whois.l.google.com",
"cheap": "whois.donuts.co",
"christmas": "whois.uniregistry.net",
"chrome": "domain-registry-whois.l.google.com",
"church": "whois.donuts.co",
"ci": "whois.nic.ci",
"city": "whois.donuts.co",
"ck": "whois.nic.ck",
"cl": "whois.nic.cl",
"claims": "whois.donuts.co",
"cleaning": "whois.donuts.co",
"click": "whois.uniregistry.net",
"clinic": "whois.donuts.co",
"clothing": "whois.donuts.co",
"club": "whois.nic.club",
"cn": "whois.cnnic.net.cn",
"co": "whois.co",
"codes": "whois.donuts.co",
"coffee": "whois.donuts.co",
"college": "whois.centralnic.com",
"cologne": "whois-fe1.pdt.cologne.tango.knipp.de",
"com": "whois.verisign-grs.com",
"community": "whois.donuts.co",
"company": "whois.donuts.co",
"computer": "whois.donuts.co",
"condos": "whois.donuts.co",
"construction": "whois.donuts.co",
"consulting": "whois.unitedtld.com",
"contractors": "whois.donuts.co",
"cooking": "whois-dub.mm-registry.com",
"cool": "whois.donuts.co",
"coop": "whois.nic.coop",
"country": "whois-dub.mm-registry.com",
"credit": "whois.donuts.co",
"creditcard": "whois.donuts.co",
"cruises": "whois.donuts.co",
"cuisinella": "whois.nic.cuisinella",
"cx": "whois.nic.cx",
"cymru": "whois.nic.cymru",
"cz": "whois.nic.cz",
"dad": "domain-registry-whois.l.google.com",
"dance": "whois.unitedtld.com",
"dating": "whois.donuts.co",
"day": "domain-registry-whois.l.google.com",
"de": "whois.denic.de",
"deals": "whois.donuts.co",
"democrat": "whois.rightside.co",
"degree": "whois.unitedtld.com",
"dental": "whois.donuts.co",
"dentist": "whois.rightside.co",
"desi": "whois.ksregistry.net",
"diamonds": "whois.donuts.co",
"diet": "whois.uniregistry.net",
"digital": "whois.donuts.co",
"direct": "whois.donuts.co",
"directory": "whois.donuts.co",
"discount": "whois.donuts.co",
"dk": "whois.dk-hostmaster.dk",
"dm": "whois.nic.dm",
"domains": "whois.donuts.co",
"durban": "durban-whois.registry.net.za",
"dvag": "whois.ksregistry.net",
"dz": "whois.nic.dz",
"eat": "domain-registry-whois.l.google.com",
"ec": "whois.nic.ec",
"edu": "whois.educause.edu",
"education": "whois.donuts.co",
"ee": "whois.eenet.ee",
"eg": "whois.ripe.net",
"email": "whois.donuts.co",
"engineer": "whois.rightside.co",
"engineering": "whois.donuts.co",
"enterprises": "whois.donuts.co",
"equipment": "whois.donuts.co",
"es": "whois.nic.es",
"esq": "domain-registry-whois.l.google.com",
"estate": "whois.donuts.co",
"eu": "whois.eu",
"eus": "whois.eus.coreregistry.net",
"events": "whois.donuts.co",
"exchange": "whois.donuts.co",
"expert": "whois.donuts.co",
"exposed": "whois.donuts.co",
"fail": "whois.donuts.co",
"farm": "whois.donuts.co",
"feedback": "whois.centralnic.com",
"fi": "whois.ficora.fi",
"finance": "whois.donuts.co",
"financial": "whois.donuts.co",
"fish": "whois.donuts.co",
"fishing": "whois-dub.mm-registry.com",
"fitness": "whois.donuts.co",
"flights": "whois.donuts.co",
"florist": "whois.donuts.co",
"flsmidth": "whois.ksregistry.net",
"fly": "domain-registry-whois.l.google.com",
"fo": "whois.nic.fo",
"foo": "domain-registry-whois.l.google.com",
"forsale": "whois.unitedtld.com",
"foundation": "whois.donuts.co",
"fr": "whois.nic.fr",
"frl": "whois.nic.frl",
"frogans": "whois-frogans.nic.fr",
"fund": "whois.donuts.co",
"furniture": "whois.donuts.co",
"futbol": "whois.unitedtld.com",
"gal": "whois.gal.coreregistry.net",
"gallery": "whois.donuts.co",
"gbiz": "domain-registry-whois.l.google.com",
"gd": "whois.nic.gd",
"gent": "whois.nic.gent",
"gg": "whois.channelisles.net",
"gi": "whois2.afilias-grs.net",
"gift": "whois.uniregistry.net",
"gifts": "whois.donuts.co",
"gives": "whois.rightside.co",
"gl": "whois.nic.gl",
"glass": "whois.donuts.co",
"gle": "domain-registry-whois.l.google.com",
"global": "whois.afilias-srs.net",
"globo": "whois.gtlds.nic.br",
"gmail": "domain-registry-whois.l.google.com",
"gmx": "whois-fe1.gmx.tango.knipp.de",
"google": "domain-registry-whois.l.google.com",
"gop": "whois-cl01.mm-registry.com",
"gov": "whois.nic.gov",
"gq": "whois.dominio.gq",
"gr": "whois.ripe.net",
"gratis": "whois.donuts.co",
"green": "whois.afilias.net",
"gripe": "whois.donuts.co",
"gs": "whois.nic.gs",
"guide": "whois.donuts.co",
"guitars": "whois.uniregistry.net",
"guru": "whois.donuts.co",
"gy": "whois.registry.gy",
"hamburg": "whois.nic.hamburg",
"haus": "whois.unitedtld.com",
"healthcare": "whois.donuts.co",
"help": "whois.uniregistry.net",
"here": "domain-registry-whois.l.google.com",
"hiphop": "whois.uniregistry.net",
"hiv": "whois.afilias-srs.net",
"hk": "whois.hkirc.hk",
"hn": "whois.nic.hn",
"holdings": "whois.donuts.co",
"holiday": "whois.donuts.co",
"homes": "whois.afilias-srs.net",
"horse": "whois-dub.mm-registry.com",
"host": "whois.nic.host",
"hosting": "whois.uniregistry.net",
"house": "whois.donuts.co",
"how": "domain-registry-whois.l.google.com",
"hr": "whois.dns.hr",
"ht": "whois.nic.ht",
"hu": "whois.nic.hu",
"ibm": "whois.nic.ibm",
"id": "whois.pandi.or.id",
"ie": "whois.domainregistry.ie",
"il": "whois.isoc.org.il",
"im": "whois.nic.im",
"immo": "whois.donuts.co",
"immobilien": "whois.unitedtld.com",
"in": "whois.inregistry.net",
"industries": "whois.donuts.co",
"info": "whois.afilias.net",
"ing": "domain-registry-whois.l.google.com",
"ink": "whois.centralnic.com",
"institute": "whois.donuts.co",
"insure": "whois.donuts.co",
"int": "whois.iana.org",
"international": "whois.donuts.co",
"investments": "whois.donuts.co",
"io": "whois.nic.io",
"iq": "whois.cmc.iq",
"ir": "whois.nic.ir",
"is": "whois.isnic.is",
"it": "whois.nic.it",
"je": "whois.channelisles.net",
"jobs": "jobswhois.verisign-grs.com",
"joburg": "joburg-whois.registry.net.za",
"jp": "whois.jprs.jp",
"juegos": "whois.uniregistry.net",
"kaufen": "whois.unitedtld.com",
"ke": "whois.kenic.or.ke",
"kg": "www.domain.kg",
"ki": "whois.nic.ki",
"kim": "whois.afilias.net",
"kitchen": "whois.donuts.co",
"kiwi": "whois.nic.kiwi",
"koeln": "whois-fe1.pdt.koeln.tango.knipp.de",
"kr": "whois.kr",
"krd": "whois.aridnrs.net.au",
"kz": "whois.nic.kz",
"la": "whois.nic.la",
"lacaixa": "whois.nic.lacaixa",
"land": "whois.donuts.co",
"lawyer": "whois.rightside.co",
"lease": "whois.donuts.co",
"lgbt": "whois.afilias.net",
"li": "whois.nic.li",
"life": "whois.donuts.co",
"lighting": "whois.donuts.co",
"limited": "whois.donuts.co",
"limo": "whois.donuts.co",
"link": "whois.uniregistry.net",
"loans": "whois.donuts.co",
"london": "whois-lon.mm-registry.com",
"lotto": "whois.afilias.net",
"lt": "whois.domreg.lt",
"ltda": "whois.afilias-srs.net",
"lu": "whois.dns.lu",
"luxe": "whois-dub.mm-registry.com",
"luxury": "whois.nic.luxury",
"lv": "whois.nic.lv",
"ly": "whois.nic.ly",
"ma": "whois.iam.net.ma",
"maison": "whois.donuts.co",
"management": "whois.donuts.co",
"mango": "whois.mango.coreregistry.net",
"market": "whois.rightside.co",
"marketing": "whois.donuts.co",
"md": "whois.nic.md",
"me": "whois.nic.me",
"media": "whois.donuts.co",
"meet": "whois.afilias.net",
"melbourne": "whois.aridnrs.net.au",
"meme": "domain-registry-whois.l.google.com",
"menu": "whois.nic.menu",
"mg": "whois.nic.mg",
"miami": "whois-dub.mm-registry.com",
"mil": "whois.internic.net",
"mini": "whois.ksregistry.net",
"mk": "whois.marnet.mk",
"ml": "whois.dot.ml",
"mn": "whois.nic.mn",
"mo": "whois.monic.mo",
"mobi": "whois.dotmobiregistry.net",
"moda": "whois.unitedtld.com",
"moe": "whois.nic.moe",
"monash": "whois.nic.monash",
"mortgage": "whois.rightside.co",
"moscow": "whois.nic.moscow",
"motorcycles": "whois.afilias-srs.net",
"mov": "domain-registry-whois.l.google.com",
"mp": "whois.nic.mp",
"ms": "whois.nic.ms",
"mu": "whois.nic.mu",
"museum": "whois.museum",
"mx": "whois.mx",
"my": "whois.mynic.my",
"mz": "whois.nic.mz",
"na": "whois.na-nic.com.na",
"name": "whois.nic.name",
"navy": "whois.rightside.co",
"nc": "whois.nc",
"net": "whois.verisign-grs.net",
"network": "whois.donuts.co",
"new": "domain-registry-whois.l.google.com",
"nexus": "domain-registry-whois.l.google.com",
"nf": "whois.nic.nf",
"ng": "whois.nic.net.ng",
"ngo": "whois.publicinterestregistry.net",
"ninja": "whois.unitedtld.com",
"nl": "whois.domain-registry.nl",
"no": "whois.norid.no",
"nra": "whois.afilias-srs.net",
"nrw": "whois.nic.nrw",
"nu": "whois.nic.nu",
"nz": "whois.srs.net.nz",
"om": "whois.registry.om",
"ong": "whois.publicinterestregistry.net",
"onl": "whois.afilias-srs.net",
"ooo": "whois.nic.ooo",
"org": "whois.pir.org",
"organic": "whois.afilias.net",
"ovh": "whois-ovh.nic.fr",
"paris": "whois-paris.nic.fr",
"partners": "whois.donuts.co",
"parts": "whois.donuts.co",
"pe": "kero.yachay.pe",
"pf": "whois.registry.pf",
"photo": "whois.uniregistry.net",
"photography": "whois.donuts.co",
"photos": "whois.donuts.co",
"physio": "whois.nic.physio",
"pics": "whois.uniregistry.net",
"pictures": "whois.donuts.co",
"pink": "whois.afilias.net",
"pizza": "whois.donuts.co",
"pl": "whois.dns.pl",
"place": "whois.donuts.co",
"plumbing": "whois.donuts.co",
"pm": "whois.nic.pm",
"pohl": "whois.ksregistry.net",
"poker": "whois.afilias.net",
"post": "whois.dotpostregistry.net",
"pr": "whois.nic.pr",
"press": "whois.nic.press",
"pro": "whois.dotproregistry.net",
"prod": "domain-registry-whois.l.google.com",
"productions": "whois.donuts.co",
"prof": "domain-registry-whois.l.google.com",
"properties": "whois.donuts.co",
"property": "whois.uniregistry.net",
"pt": "whois.dns.pt",
"pub": "whois.unitedtld.com",
"pw": "whois.nic.pw",
"qa": "whois.registry.qa",
"quebec": "whois.quebec.rs.corenic.net",
"re": "whois.nic.re",
"recipes": "whois.donuts.co",
"red": "whois.afilias.net",
"rehab": "whois.rightside.co",
"reise": "whois.nic.reise",
"reisen": "whois.donuts.co",
"rentals": "whois.donuts.co",
"repair": "whois.donuts.co",
"report": "whois.donuts.co",
"republican": "whois.rightside.co",
"rest": "whois.centralnic.com",
"restaurant": "whois.donuts.co",
"reviews": "whois.unitedtld.com",
"rich": "whois.afilias-srs.net",
"rio": "whois.gtlds.nic.br",
"rip": "whois.rightside.co",
"ro": "whois.rotld.ro",
"rocks": "whois.unitedtld.com",
"rodeo": "whois-dub.mm-registry.com",
"rs": "whois.rnids.rs",
"rsvp": "domain-registry-whois.l.google.com",
"ru": "whois.ripn.net",
"ruhr": "whois.nic.ruhr",
"sa": "whois.nic.net.sa",
"saarland": "whois.ksregistry.net",
"sarl": "whois.donuts.co",
"sb": "whois.nic.net.sb",
"sc": "whois2.afilias-grs.net",
"sca": "whois.nic.scb",
"schmidt": "whois.nic.schmidt",
"schule": "whois.donuts.co",
"scot": "whois.scot.coreregistry.net",
"se": "whois.iis.se",
"services": "whois.donuts.co",
"sexy": "whois.uniregistry.net",
"sg": "whois.nic.net.sg",
"sh": "whois.nic.sh",
"shiksha": "whois.afilias.net",
"shoes": "whois.donuts.co",
"si": "whois.arnes.si",
"singles": "whois.donuts.co",
"sk": "whois.sk-nic.sk",
"sm": "whois.nic.sm",
"sn": "whois.nic.sn",
"so": "whois.nic.so",
"social": "whois.unitedtld.com",
"software": "whois.rightside.co",
"solar": "whois.donuts.co",
"solutions": "whois.donuts.co",
"soy": "domain-registry-whois.l.google.com",
"space": "whois.nic.space",
"spiegel": "whois.ksregistry.net",
"st": "whois.nic.st",
"su": "whois.tcinet.ru",
"supplies": "whois.donuts.co",
"supply": "whois.donuts.co",
"support": "whois.donuts.co",
"surf": "whois-dub.mm-registry.com",
"surgery": "whois.donuts.co",
"sx": "whois.sx",
"sy": "whois.tld.sy",
"systems": "whois.donuts.co",
"tatar": "whois.nic.tatar",
"tattoo": "whois.uniregistry.net",
"tax": "whois.donuts.co",
"tc": "whois.meridiantld.net",
"technology": "whois.donuts.co",
"tel": "whois.nic.tel",
"tf": "whois.nic.tf",
"th": "whois.thnic.co.th",
"tienda": "whois.donuts.co",
"tips": "whois.donuts.co",
"tirol": "whois.nic.tirol",
"tj": "whois.nic.tj",
"tk": "whois.dot.tk",
"tl": "whois.nic.tl",
"tm": "whois.nic.tm",
"tn": "whois.ati.tn",
"to": "whois.tonic.to",
"today": "whois.donuts.co",
"tools": "whois.donuts.co",
"top": "whois.nic.top",
"town": "whois.donuts.co",
"toys": "whois.donuts.co",
"tp": "whois.nic.tl",
"tr": "whois.nic.tr",
"training": "whois.donuts.co",
"travel": "whois.nic.travel",
"tui": "whois.ksregistry.net",
"tv": "tvwhois.verisign-grs.com",
"tw": "whois.twnic.net.tw",
"tz": "whois.tznic.or.tz",
"ua": "whois.ua",
"ug": "whois.co.ug",
"uk": "whois.nic.uk",
"university": "whois.donuts.co",
"uol": "whois.gtlds.nic.br",
"us": "whois.nic.us",
"uy": "whois.nic.org.uy",
"uz": "whois.cctld.uz",
"vacations": "whois.donuts.co",
"vc": "whois2.afilias-grs.net",
"ve": "whois.nic.ve",
"vegas": "whois.afilias-srs.net",
"ventures": "whois.donuts.co",
"vermögensberater": "whois.ksregistry.net",
"vermögensberatung": "whois.ksregistry.net",
"versicherung": "whois.nic.versicherung",
"vet": "whois.rightside.co",
"vg": "ccwhois.ksregistry.net",
"viajes": "whois.donuts.co",
"villas": "whois.donuts.co",
"vision": "whois.donuts.co",
"vlaanderen": "whois.nic.vlaanderen",
"vodka": "whois-dub.mm-registry.com",
"vote": "whois.afilias.net",
"voting": "whois.voting.tld-box.at",
"voto": "whois.afilias.net",
"voyage": "whois.donuts.co",
"vu": "vunic.vu",
"wf": "whois.nic.wf",
"wales": "whois.nic.wales",
"wang": "whois.gtld.knet.cn",
"watch": "whois.donuts.co",
"website": "whois.nic.website",
"wed": "whois.nic.wed",
"wedding": "whois-dub.mm-registry.com",
"wf": "whois.nic.wf",
"wien": "whois.nic.wien",
"wiki": "whois.nic.wiki",
"wme": "whois.centralnic.com",
"work": "whois-dub.mm-registry.com",
"works": "whois.donuts.co",
"world": "whois.donuts.co",
"ws": "whois.website.ws",
"wtc": "whois.nic.wtc",
"wtf": "whois.donuts.co",
"xxx": "whois.nic.xxx",
"xyz": "whois.nic.xyz",
"yachts": "whois.afilias-srs.net",
"yoga": "whois-dub.mm-registry.com",
"youtube": "domain-registry-whois.l.google.com",
"yt": "whois.nic.yt",
"zip": "domain-registry-whois.l.google.com",
"zm": "whois.nic.zm",
"zone": "whois.donuts.co",
"дети": "whois.nic.xn--d1acj3b",
"москва": "whois.nic.xn--80adxhks",
"онлайн": "whois.online.rs.corenic.net",
"орг": "whois.publicinterestregistry.net",
"рус": "whois.nic.xn--p1acf",
"рф": "whois.tcinet.ru",
"сайт": "whois.site.rs.corenic.net",
"укр": "whois.dotukr.com",
"қаз": "whois.nic.kz",
"الجزائر": "whois.nic.dz",
"السعودية": "whois.nic.net.sa",
"امارات": "whois.aeda.net.ae",
"ایران": "whois.nic.ir",
"بازار": "whois.bazaar.coreregistry.net",
"سورية": "whois.tld.sy",
"شبكة": "whois.nic.xn--ngbc5azd",
"عمان": "whois.registry.om",
"قطر": "whois.registry.qa",
"مليسيا": "whois.mynic.my",
"موقع": "whois.afilias-srs.net",
"சிங்கப்பூர்": "whois.sgnic.sg",
"ไทย": "whois.thnic.co.th",
"みんな": "domain-registry-whois.l.google.com",
"中信": "whois.gtld.knet.cn",
"中国": "cwhois.cnnic.cn",
"中國": "cwhois.cnnic.cn",
"中文网": "whois.afilias-srs.net",
"企业": "whois.donuts.co",
"佛山": "whois.ngtld.cn",
"公司": "whois.ngtld.cn",
"公益": "whois.conac.cn",
"台湾": "whois.twnic.net.tw",
"台灣": "whois.twnic.net.tw",
"商城": "whois.gtld.knet.cn",
"在线": "whois.afilias-srs.net",
"广东": "whois.ngtld.cn",
"我爱你": "whois.gtld.knet.cn",
"手机": "whois.afilias-srs.net",
"政务": "whois.conac.cn",
"新加坡": "whois.sgnic.sg",
"新加坡": "whois.sgnic.sg",
"游戏": "whois.donuts.co",
"移动": "whois.afilias.net",
"组织机构": "whois.publicinterestregistry.net",
"网络": "whois.ngtld.cn",
"集团": "whois.gtld.knet.cn",
"香港": "whois.hkirc.hk"
},
"ip": [
"whois.lacnic.net",
"whois.apnic.net",
"whois.arin.net",
"whois.ripe.net"
]
}

View file

@ -32,6 +32,7 @@ require_once ROOT .'_sakura/components/Configuration.php';
require_once ROOT .'_sakura/components/Templates.php';
require_once ROOT .'_sakura/components/Sessions.php';
require_once ROOT .'_sakura/components/Users.php';
require_once ROOT .'_sakura/components/Whois.php';
// Generate path to database driver
$_DBNGNPATH = ROOT .'_sakura/components/database/'. $sakuraConf['db']['driver'] .'.php';

View file

@ -0,0 +1,60 @@
<html>
<head>
<style type="text/css">
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
background: #FBEEFF;
color: #330066;
}
a {
color: #22E;
text-decoration: none;
}
a:hover {
color: #22E;
text-decoration: underline;
}
a:active {
color: #E22;
text-decoration: underline;
}
.head {
background: #9472B2;
padding-left: 5px;
font-size: 1.5em;
line-height: 1.4em;
text-align: left;
}
.foot {
background: #9472B2;
line-height: 1em;
font-size: .8em;
padding: 4px 5px;
text-align: right;
}
.cont {
font-size: 12px;
line-height: 20px;
}
</style>
</head>
<body>
<table style="width: 100%;">
<tr>
<td class="head">
<strong>{{ sitename }}</strong>
</td>
</tr>
<tr>
<td class="cont">
{{ contents }}
</td>
</tr>
<tr>
<td class="foot">
<strong>This message has been sent to the email address associated with your <a href="{{ siteurl }}">{{ sitename }}</a> account.</strong>
</td>
</tr>
</table>
</body>
</html>

View file

@ -52,6 +52,11 @@
<!-- Navigation menu, displayed on left side of the bar. -->
<a class="menu-item" href="//{{ sakura.urls.main }}/" title="Return to the front page of Flashii">Home</a>
<a class="menu-item" href="//{{ sakura.urls.main }}/news" title="Here you can read updates on Flashii">News</a>
<a class="menu-item" href="//{{ sakura.urls.chat }}/" title="Chat with other Flashii members">Chat</a>
{% if user.checklogin %}
<a class="menu-item" href="//{{ sakura.urls.main }}/members" title="View a list with all the activated user accounts">Members</a>
<a class="menu-item menu-donate" href="//{{ sakura.urls.main }}/donate" title="Give us money to keep the site (and other services) up and running">Donate</a>
{% endif %}
</div>
<div class="menu-ucp" id="navMenuUser">
<!-- User menu, displayed on right side of the bar. -->

View file

@ -84,6 +84,7 @@ if(
'USER_NOT_EXIST' => 'The user you tried to log into does not exist.',
'INCORRECT_PASSWORD' => 'The password you entered was invalid.',
'DEACTIVATED' => 'Your account is deactivated.',
'NO_LOGIN' => 'Logging into this account is disabled.',
'LEGACY_SUCCESS' => 'Login successful! Taking you to the password changing page...',
'LOGIN_SUCESS' => 'Login successful!'
];
@ -153,10 +154,19 @@ $renderData['auth'] = [
)
),
'blockRegister' => [
'do' => true,
'username' => 'test'
'do' => false
]
];
// Check if a user has already registered from the current IP address
if(count($regUserIP = Users::getUsersByIP(Main::getRemoteIP()))) {
$renderData['auth']['blockRegister'] = [
'do' => true,
'username' => $regUserIP[array_rand($regUserIP)]['username']
];
}
// Print page contents
print Templates::render('main/authenticate.tpl', $renderData);