r20150905

Signed-off-by: Flashwave <me@flash.moe>
This commit is contained in:
flash 2015-09-05 18:11:04 +02:00
parent 57542ac936
commit e67be33619
50 changed files with 970 additions and 687 deletions

View file

@ -4,12 +4,12 @@ This is a list of people who have contributed to Sakura and also a list of the l
## People ## People
| Name | Contribution | | Name | Contribution |
| ---- | ------------ | | ------------- | ---------------------------------------------------------- |
| Flashwave | Project leader and main developer. | | Flashwave | Project leader and main developer. |
| MallocNull | Internal advice and pointing out my (Flashwave) stupidity. | | MallocNull | Internal advice and pointing out my (Flashwave) stupidity. |
| kamilrakowski | Providing a huge pile of security advice and fixes. | | kamilrakowski | Providing a huge pile of security advice and fixes. |
| RandomGuy | Mostly security advice as well. | | RandomGuy | Mostly security advice as well. |
## Libraries ## Libraries

View file

@ -7,8 +7,11 @@
// Filesystem path to the _sakura folder WITHOUT an ending / // Filesystem path to the _sakura folder WITHOUT an ending /
// This can also be set before an include of this file in case // This can also be set before an include of this file in case
// you're using git to keep in sync and don't want conflicts // you're using git to keep in sync and don't want conflicts
if(!isset($sockSakuraPath)) if(!isset($sockSakuraPath)) {
$sockSakuraPath = '';
$sockSakuraPath = '';
}
/* * * DON'T EDIT ANYTHING BELOW THIS LINE * * */ /* * * DON'T EDIT ANYTHING BELOW THIS LINE * * */
@ -18,7 +21,8 @@ require_once $sockSakuraPath .'/sakura.php';
use sockchat\Auth; use sockchat\Auth;
use Sakura\Session; use Sakura\Session;
use Sakura\Users; use Sakura\Users;
use Sakura\SockChat; use Sakura\Permissions;
use Sakura\User;
if(Auth::getPageType() == AUTH_FETCH) { if(Auth::getPageType() == AUTH_FETCH) {
@ -29,9 +33,12 @@ if(Auth::getPageType() == AUTH_FETCH) {
Auth::AppendArguments([Session::$userId, Session::$sessionId]); Auth::AppendArguments([Session::$userId, Session::$sessionId]);
Auth::Accept(); Auth::Accept();
} else } else {
Auth::Deny(); Auth::Deny();
}
} else { } else {
// Get arguments // Get arguments
@ -41,12 +48,8 @@ if(Auth::getPageType() == AUTH_FETCH) {
// Check if session is active else deny // Check if session is active else deny
if(Session::checkSession($uid, $sid)) { if(Session::checkSession($uid, $sid)) {
// Get user and rank data // Check if they can access the chat
$user = Users::getUser($uid); if(Permissions::check('SITE', 'DEACTIVATED', $uid, 1) && Permissions::check('SITE', 'RESTRICTED', $uid, 1)) {
$rank = Users::getRank($user['rank_main']);
// Deny group and user id 0
if($user['id'] == 0 || $rank['id'] == 0 || $user['password_algo'] == 'nologin') {
Auth::Deny(); Auth::Deny();
Auth::Serve(); Auth::Serve();
@ -54,39 +57,35 @@ if(Auth::getPageType() == AUTH_FETCH) {
} }
// Create a user object
$user = new User($uid);
// Set the user's data // Set the user's data
Auth::SetUserData( Auth::SetUserData(
$user['id'], $user->data['id'],
$user['username'], $user->data['username'],
$user['name_colour'] == null ? $rank['colour'] : $user['name_colour'] $user->colour()
); );
// Get the user's permissions
$perms = SockChat::getUserPermissions($user['id']);
// Check if they can access the chat
if(!$perms['access']) {
Auth::Deny();
Auth::Serve();
exit;
}
// Set the common permissions // Set the common permissions
Auth::SetCommonPermissions( Auth::SetCommonPermissions(
$perms['rank'], bindec(Permissions::getUserPermissions($uid)['SITE']),
$perms['type'], Permissions::check('MANAGE', 'USE_MANAGE', $uid, 1) ? 1 : 0,
$perms['logs'], Permissions::check('SITE', 'CREATE_BACKGROUND', $uid, 1) ? 1 : 0,
$perms['nick'], Permissions::check('SITE', 'CHANGE_USERNAME', $uid, 1) ? 1 : 0,
$perms['channel'] Permissions::check('SITE', 'MULTIPLE_GROUPS', $uid, 1) ? 2 : (
Permissions::check('SITE', 'CREATE_GROUP', $uid, 1) ? 1 : 0
)
); );
Auth::Accept(); Auth::Accept();
} else } else {
Auth::Deny(); Auth::Deny();
}
} }
// Serve the authentication data // Serve the authentication data

View file

@ -5,8 +5,6 @@ SET time_zone = '+00:00';
SET foreign_key_checks = 0; SET foreign_key_checks = 0;
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'; SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
DROP DATABASE IF EXISTS `sakura-development`;
CREATE DATABASE `sakura-development` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */;
USE `sakura-development`; USE `sakura-development`;
DROP TABLE IF EXISTS `sakura_actioncodes`; DROP TABLE IF EXISTS `sakura_actioncodes`;
@ -17,7 +15,7 @@ CREATE TABLE `sakura_actioncodes` (
`actkey` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'The URL key for using this code.', `actkey` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'The URL key for using this code.',
`instruction` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Things the backend should do upon using this code', `instruction` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Things the backend should do upon using this code',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_apikeys`; DROP TABLE IF EXISTS `sakura_apikeys`;
@ -54,7 +52,7 @@ CREATE TABLE `sakura_bbcodes` (
`description` varchar(512) COLLATE utf8_bin NOT NULL COMMENT 'Description of what this does.', `description` varchar(512) COLLATE utf8_bin NOT NULL COMMENT 'Description of what this does.',
`on_posting` tinyint(1) unsigned NOT NULL COMMENT 'Set if this bbcode is displayed on the posting page.', `on_posting` tinyint(1) unsigned NOT NULL COMMENT 'Set if this bbcode is displayed on the posting page.',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `sakura_bbcodes` (`id`, `regex`, `replace`, `title`, `description`, `on_posting`) VALUES INSERT INTO `sakura_bbcodes` (`id`, `regex`, `replace`, `title`, `description`, `on_posting`) VALUES
(1, '/\\[b\\](.*?)\\[\\/b\\]/is', '<b>$1</b>', 'Bold', 'Make text bold. Usage: [b]text[/b].', 1), (1, '/\\[b\\](.*?)\\[\\/b\\]/is', '<b>$1</b>', 'Bold', 'Make text bold. Usage: [b]text[/b].', 1),
@ -65,8 +63,7 @@ INSERT INTO `sakura_bbcodes` (`id`, `regex`, `replace`, `title`, `description`,
(6, '/\\[url=([a-zA-Z0-9\\.\\$\\-\\_\\.\\+\\*\\!\\\'\\(\\)\\/\\:\\#]+)\\](.*?)\\[\\/url\\]/is', '<a href=\"$1\" target=\"_blank\">$2</a>', 'Link', 'Embed a URL. Usage: [url=http://google.com]Link to google![/url]', 0), (6, '/\\[url=([a-zA-Z0-9\\.\\$\\-\\_\\.\\+\\*\\!\\\'\\(\\)\\/\\:\\#]+)\\](.*?)\\[\\/url\\]/is', '<a href=\"$1\" target=\"_blank\">$2</a>', 'Link', 'Embed a URL. Usage: [url=http://google.com]Link to google![/url]', 0),
(7, '/\\[url\\]([a-zA-Z0-9\\.\\$\\-\\_\\.\\+\\*\\!\\\'\\(\\)\\/\\:\\#]+)\\[\\/url\\]/is', '<a href=\"$1\" target=\"_blank\">$1</a>', 'Link', 'Make a link clickable (if the automatic algorithm doesn\'t do it already). Usage: [url]http://google.com[/url]', 1), (7, '/\\[url\\]([a-zA-Z0-9\\.\\$\\-\\_\\.\\+\\*\\!\\\'\\(\\)\\/\\:\\#]+)\\[\\/url\\]/is', '<a href=\"$1\" target=\"_blank\">$1</a>', 'Link', 'Make a link clickable (if the automatic algorithm doesn\'t do it already). Usage: [url]http://google.com[/url]', 1),
(8, '/\\[quote\\=\\\"(.+)\\\"\\](.+)\\[\\/quote]/is', '<div class=\"quote\"><div class=\"quotee\">$1 wrote:</div><div class=\"text\">$2</div></div>', 'Quote', 'Quote a user\'s post. Usage: [quote=Flashwave]nookls is pretty[/quote]', 0), (8, '/\\[quote\\=\\\"(.+)\\\"\\](.+)\\[\\/quote]/is', '<div class=\"quote\"><div class=\"quotee\">$1 wrote:</div><div class=\"text\">$2</div></div>', 'Quote', 'Quote a user\'s post. Usage: [quote=Flashwave]nookls is pretty[/quote]', 0),
(9, '/\\[quote\\](.+)\\[\\/quote]/is', '<div class=\"quote\"><div class=\"quotee\">Quote:</div><div class=\"text\">$1</div></div>', 'Quote', 'Quote a user\'s post. Usage: [quote]nookls is pretty[/quote]', 1) (9, '/\\[quote\\](.+)\\[\\/quote]/is', '<div class=\"quote\"><div class=\"quotee\">Quote:</div><div class=\"text\">$1</div></div>', 'Quote', 'Quote a user\'s post. Usage: [quote]nookls is pretty[/quote]', 1);
ON DUPLICATE KEY UPDATE `id` = VALUES(`id`), `regex` = VALUES(`regex`), `replace` = VALUES(`replace`), `title` = VALUES(`title`), `description` = VALUES(`description`), `on_posting` = VALUES(`on_posting`);
DROP TABLE IF EXISTS `sakura_config`; DROP TABLE IF EXISTS `sakura_config`;
CREATE TABLE `sakura_config` ( CREATE TABLE `sakura_config` (
@ -83,15 +80,15 @@ INSERT INTO `sakura_config` (`config_name`, `config_value`) VALUES
('cookie_path', '/'), ('cookie_path', '/'),
('site_style', 'yuuno'), ('site_style', 'yuuno'),
('manage_style', 'broomcloset'), ('manage_style', 'broomcloset'),
('smtp_server', 'smtp-mail.outlook.com'), ('smtp_server', ''),
('smtp_auth', '1'), ('smtp_auth', ''),
('smtp_secure', 'tls'), ('smtp_secure', ''),
('smtp_port', '587'), ('smtp_port', ''),
('smtp_username', 'flashii@outlook.com'), ('smtp_username', ''),
('smtp_password', ''), ('smtp_password', ''),
('smtp_replyto_mail', 'admin@flashii.net'), ('smtp_replyto_mail', 'admin@flashii.net'),
('smtp_replyto_name', 'Flashwave'), ('smtp_replyto_name', 'Flashwave'),
('smtp_from_email', 'flashii@outlook.com'), ('smtp_from_email', ''),
('smtp_from_name', 'Flashii Noreply'), ('smtp_from_name', 'Flashii Noreply'),
('sitename', 'Cutting Edgii'), ('sitename', 'Cutting Edgii'),
('recaptcha', '0'), ('recaptcha', '0'),
@ -117,9 +114,6 @@ INSERT INTO `sakura_config` (`config_name`, `config_value`) VALUES
('premium_amount_max', '24'), ('premium_amount_max', '24'),
('alumni_rank_id', '9'), ('alumni_rank_id', '9'),
('url_main', 'flashii.test'), ('url_main', 'flashii.test'),
('disqus_shortname', 'flashii'),
('disqus_api_key', ''),
('disqus_api_secret', ''),
('front_page_news_posts', '3'), ('front_page_news_posts', '3'),
('date_format', 'D Y-m-d H:i:s T'), ('date_format', 'D Y-m-d H:i:s T'),
('news_posts_per_page', '3'), ('news_posts_per_page', '3'),
@ -131,9 +125,6 @@ INSERT INTO `sakura_config` (`config_name`, `config_value`) VALUES
('url_api', 'api.flashii.test'), ('url_api', 'api.flashii.test'),
('content_path', '/content'), ('content_path', '/content'),
('user_uploads', 'uploads'), ('user_uploads', 'uploads'),
('no_avatar_img', 'main/content/images/no-av.png'),
('deactivated_avatar_img', 'main/content/images/deactivated-av.png'),
('banned_avatar_img', 'main/content/images/banned-av.png'),
('no_background_img', 'main/content/pixel.png'), ('no_background_img', 'main/content/pixel.png'),
('no_header_img', 'main/content/images/triangles.png'), ('no_header_img', 'main/content/images/triangles.png'),
('pixel_img', 'main/content/pixel.png'), ('pixel_img', 'main/content/pixel.png'),
@ -142,8 +133,13 @@ INSERT INTO `sakura_config` (`config_name`, `config_value`) VALUES
('background_max_height', '1440'), ('background_max_height', '1440'),
('background_min_height', '16'), ('background_min_height', '16'),
('background_min_width', '16'), ('background_min_width', '16'),
('max_online_time', '500') ('max_online_time', '500'),
ON DUPLICATE KEY UPDATE `config_name` = VALUES(`config_name`), `config_value` = VALUES(`config_value`); ('no_avatar_img', 'main/content/data/{{ TPL }}/images/no-av.png'),
('deactivated_avatar_img', 'main/content/data/{{ TPL }}/images/deactivated-av.png'),
('banned_avatar_img', 'main/content/data/{{ TPL }}/images/banned-av.png'),
('session_check', '2'),
('url_rewrite', '1'),
('members_per_page', '30');
DROP TABLE IF EXISTS `sakura_emoticons`; DROP TABLE IF EXISTS `sakura_emoticons`;
CREATE TABLE `sakura_emoticons` ( CREATE TABLE `sakura_emoticons` (
@ -189,8 +185,7 @@ INSERT INTO `sakura_emoticons` (`emote_string`, `emote_path`) VALUES
(':wtf:', '/content/images/emoticons/wtf.gif'), (':wtf:', '/content/images/emoticons/wtf.gif'),
(':sleep:', '/content/images/emoticons/zzz.gif'), (':sleep:', '/content/images/emoticons/zzz.gif'),
(':what:', '/content/images/emoticons/what.png'), (':what:', '/content/images/emoticons/what.png'),
(':smug:', '/content/images/emoticons/smug.png') (':smug:', '/content/images/emoticons/smug.png');
ON DUPLICATE KEY UPDATE `emote_string` = VALUES(`emote_string`), `emote_path` = VALUES(`emote_path`);
DROP TABLE IF EXISTS `sakura_faq`; DROP TABLE IF EXISTS `sakura_faq`;
CREATE TABLE `sakura_faq` ( CREATE TABLE `sakura_faq` (
@ -199,7 +194,7 @@ CREATE TABLE `sakura_faq` (
`question` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'The question.', `question` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'The question.',
`answer` text COLLATE utf8_bin NOT NULL COMMENT 'The answer.', `answer` text COLLATE utf8_bin NOT NULL COMMENT 'The answer.',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_forums`; DROP TABLE IF EXISTS `sakura_forums`;
@ -212,7 +207,7 @@ CREATE TABLE `sakura_forums` (
`forum_type` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT 'Forum type, 0 for regular board, 1 for category and 2 for link.', `forum_type` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT 'Forum type, 0 for regular board, 1 for category and 2 for link.',
`forum_icon` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Display icon for the forum.', `forum_icon` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Display icon for the forum.',
PRIMARY KEY (`forum_id`) PRIMARY KEY (`forum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_friends`; DROP TABLE IF EXISTS `sakura_friends`;
@ -265,18 +260,19 @@ CREATE TABLE `sakura_messages` (
`subject` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Title of the message', `subject` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Title of the message',
`content` text COLLATE utf8_bin NOT NULL COMMENT 'Contents of the message.', `content` text COLLATE utf8_bin NOT NULL COMMENT 'Contents of the message.',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_news`; DROP TABLE IF EXISTS `sakura_news`;
CREATE TABLE `sakura_news` ( CREATE TABLE `sakura_news` (
`id` bigint(128) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.', `id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`uid` bigint(128) unsigned NOT NULL COMMENT 'ID of user who posted this news message.', `category` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Category ID.',
`date` int(64) unsigned NOT NULL COMMENT 'News post timestamp.', `uid` bigint(255) unsigned NOT NULL COMMENT 'ID of user who posted this news message.',
`date` int(11) unsigned NOT NULL COMMENT 'News post timestamp.',
`title` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Title of the post.', `title` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Title of the post.',
`content` text COLLATE utf8_bin NOT NULL COMMENT 'Contents of the post', `content` text COLLATE utf8_bin NOT NULL COMMENT 'Contents of the post',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_notifications`; DROP TABLE IF EXISTS `sakura_notifications`;
@ -294,7 +290,7 @@ CREATE TABLE `sakura_notifications` (
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `uid` (`uid`), KEY `uid` (`uid`),
CONSTRAINT `sakura_notifications_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE CONSTRAINT `sakura_notifications_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_optionfields`; DROP TABLE IF EXISTS `sakura_optionfields`;
@ -308,8 +304,9 @@ CREATE TABLE `sakura_optionfields` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `sakura_optionfields` (`id`, `name`, `description`, `formtype`, `require_perm`) VALUES INSERT INTO `sakura_optionfields` (`id`, `name`, `description`, `formtype`, `require_perm`) VALUES
('profileBackgroundSiteWide', 'Display profile background site wide', 'This will make the profile background you set on your profile appear on the entire site (except on other profiles).', 'checkbox', 'CREATE_BACKGROUND') ('disableProfileParallax', 'Disable Parallaxing', 'This will stop your background from responding to your mouse movement, this will only affect your background.', 'checkbox', 'CHANGE_BACKGROUND'),
ON DUPLICATE KEY UPDATE `id` = VALUES(`id`), `name` = VALUES(`name`), `description` = VALUES(`description`), `formtype` = VALUES(`formtype`), `require_perm` = VALUES(`require_perm`); ('profileBackgroundSiteWide', 'Display profile background site wide', 'This will make the profile background you set on your profile appear on the entire site (except on other profiles).', 'checkbox', 'CREATE_BACKGROUND'),
('useMisaki', 'Use the testing style', 'This will make the site use the new Misaki style instead of Yuuno.', 'checkbox', 'ALTER_PROFILE');
DROP TABLE IF EXISTS `sakura_permissions`; DROP TABLE IF EXISTS `sakura_permissions`;
CREATE TABLE `sakura_permissions` ( CREATE TABLE `sakura_permissions` (
@ -322,16 +319,16 @@ CREATE TABLE `sakura_permissions` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `sakura_permissions` (`rid`, `uid`, `siteperms`, `manageperms`, `forumperms`, `rankinherit`) VALUES INSERT INTO `sakura_permissions` (`rid`, `uid`, `siteperms`, `manageperms`, `forumperms`, `rankinherit`) VALUES
(1, 0, '0000000000000000000000000001', '000', '1', '000'), (1, 0, '0000000000000000000000000001', '00', '0', '000'),
(2, 0, '0000111111111100111101101100', '000', '1', '000'), (2, 0, '0000111111111100111101101100', '00', '1', '000'),
(3, 0, '0001111111111111111111111100', '011', '1', '000'), (3, 0, '0001111111111111111111111100', '11', '1', '000'),
(4, 0, '0111111111111111111111111100', '111', '1', '000'), (4, 0, '1111111111111111111111111100', '11', '1', '000'),
(5, 0, '0001111111111111111111111100', '101', '1', '000'), (5, 0, '0001111111111111111111111100', '11', '1', '000'),
(6, 0, '0000111111111100111101101100', '000', '0', '000'), (6, 0, '0000111111111100111101101100', '00', '0', '000'),
(7, 0, '0001111111111111111111111100', '011', '1', '000'), (7, 0, '0001111111111111111111111100', '01', '1', '000'),
(8, 0, '0001111111111111111111111100', '000', '1', '000'), (8, 0, '0001111111111111111111111100', '00', '1', '000'),
(9, 0, '0001111111111111111111111100', '000', '1', '000') (9, 0, '0001111111111111111111111100', '00', '1', '000'),
ON DUPLICATE KEY UPDATE `rid` = VALUES(`rid`), `uid` = VALUES(`uid`), `siteperms` = VALUES(`siteperms`), `manageperms` = VALUES(`manageperms`), `forumperms` = VALUES(`forumperms`), `rankinherit` = VALUES(`rankinherit`); (10, 0, '0000000011010100101000100010', '00', '0', '000');
DROP TABLE IF EXISTS `sakura_posts`; DROP TABLE IF EXISTS `sakura_posts`;
CREATE TABLE `sakura_posts` ( CREATE TABLE `sakura_posts` (
@ -355,7 +352,7 @@ CREATE TABLE `sakura_posts` (
KEY `poster_id` (`poster_id`), KEY `poster_id` (`poster_id`),
CONSTRAINT `sakura_posts_ibfk_1` FOREIGN KEY (`topic_id`) REFERENCES `sakura_topics` (`topic_id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `sakura_posts_ibfk_1` FOREIGN KEY (`topic_id`) REFERENCES `sakura_topics` (`topic_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sakura_posts_ibfk_2` FOREIGN KEY (`forum_id`) REFERENCES `sakura_forums` (`forum_id`) ON DELETE CASCADE ON UPDATE CASCADE CONSTRAINT `sakura_posts_ibfk_2` FOREIGN KEY (`forum_id`) REFERENCES `sakura_forums` (`forum_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_premium`; DROP TABLE IF EXISTS `sakura_premium`;
@ -368,6 +365,17 @@ CREATE TABLE `sakura_premium` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_premium_log`;
CREATE TABLE `sakura_premium_log` (
`id` int(16) unsigned NOT NULL AUTO_INCREMENT COMMENT 'MySQL Generated ID used for sorting.',
`uid` bigint(255) unsigned NOT NULL COMMENT 'User ID of purchaser',
`amount` float NOT NULL COMMENT 'Amount that was transferred.',
`date` int(11) unsigned NOT NULL COMMENT 'Date when the purchase was made.',
`comment` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'A short description of the action taken.',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=143 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_profilefields`; DROP TABLE IF EXISTS `sakura_profilefields`;
CREATE TABLE `sakura_profilefields` ( CREATE TABLE `sakura_profilefields` (
`id` int(64) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID used for ordering on the userpage.', `id` int(64) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID used for ordering on the userpage.',
@ -378,7 +386,7 @@ CREATE TABLE `sakura_profilefields` (
`description` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Description of the field displayed in the control panel.', `description` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Description of the field displayed in the control panel.',
`additional` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Undocumented JSON array containing special options if needed (probably only going to be used for the YouTube field).', `additional` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Undocumented JSON array containing special options if needed (probably only going to be used for the YouTube field).',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `sakura_profilefields` (`id`, `name`, `formtype`, `islink`, `linkformat`, `description`, `additional`) VALUES INSERT INTO `sakura_profilefields` (`id`, `name`, `formtype`, `islink`, `linkformat`, `description`, `additional`) VALUES
(1, 'Website', 'url', 1, '{{ VAL }}', 'URL to your website', ''), (1, 'Website', 'url', 1, '{{ VAL }}', 'URL to your website', ''),
@ -392,8 +400,7 @@ INSERT INTO `sakura_profilefields` (`id`, `name`, `formtype`, `islink`, `linkfor
(9, 'Origin', 'text', 0, '', 'Your Origin User ID', ''), (9, 'Origin', 'text', 0, '', 'Your Origin User ID', ''),
(10, 'Xbox Live', 'text', 1, 'https://account.xbox.com/en-GB/Profile?Gamertag={{ VAL }}', 'Your Xbox User ID', ''), (10, 'Xbox Live', 'text', 1, 'https://account.xbox.com/en-GB/Profile?Gamertag={{ VAL }}', 'Your Xbox User ID', ''),
(11, 'PSN', 'text', 1, 'http://psnprofiles.com/{{ VAL }}', 'Your PSN User ID', ''), (11, 'PSN', 'text', 1, 'http://psnprofiles.com/{{ VAL }}', 'Your PSN User ID', ''),
(12, 'Last.fm', 'text', 1, 'http://last.fm/user/{{ VAL }}', 'Your Last.fm username', '') (12, 'Last.fm', 'text', 1, 'http://last.fm/user/{{ VAL }}', 'Your Last.fm username', '');
ON DUPLICATE KEY UPDATE `id` = VALUES(`id`), `name` = VALUES(`name`), `formtype` = VALUES(`formtype`), `islink` = VALUES(`islink`), `linkformat` = VALUES(`linkformat`), `description` = VALUES(`description`), `additional` = VALUES(`additional`);
DROP TABLE IF EXISTS `sakura_ranks`; DROP TABLE IF EXISTS `sakura_ranks`;
CREATE TABLE `sakura_ranks` ( CREATE TABLE `sakura_ranks` (
@ -405,7 +412,7 @@ CREATE TABLE `sakura_ranks` (
`description` text COLLATE utf8_bin NOT NULL COMMENT 'A description of what a user of this rank can do/is supposed to do.', `description` text COLLATE utf8_bin NOT NULL COMMENT 'A description of what a user of this rank can do/is supposed to do.',
`title` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Default user title if user has none set.', `title` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Default user title if user has none set.',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `sakura_ranks` (`id`, `name`, `multi`, `hidden`, `colour`, `description`, `title`) VALUES INSERT INTO `sakura_ranks` (`id`, `name`, `multi`, `hidden`, `colour`, `description`, `title`) VALUES
(1, 'Deactivated', 0, 1, '#555', 'Users that are yet to be activated or that deactivated their own account.', 'Deactivated'), (1, 'Deactivated', 0, 1, '#555', 'Users that are yet to be activated or that deactivated their own account.', 'Deactivated'),
@ -415,9 +422,9 @@ INSERT INTO `sakura_ranks` (`id`, `name`, `multi`, `hidden`, `colour`, `descript
(5, 'Developer', 1, 0, '#824CA0', 'Users that either create or test new features of the site.', 'Staff'), (5, 'Developer', 1, 0, '#824CA0', 'Users that either create or test new features of the site.', 'Staff'),
(6, 'Bot', 1, 1, '#9E8DA7', 'Reserved user accounts for services.', 'Bot'), (6, 'Bot', 1, 1, '#9E8DA7', 'Reserved user accounts for services.', 'Bot'),
(7, 'Chat moderator', 1, 0, '#09F', 'Moderators of the chat room.', 'Staff'), (7, 'Chat moderator', 1, 0, '#09F', 'Moderators of the chat room.', 'Staff'),
(8, 'Tenshi', 0, 0, '#EE9400', 'Users that donated $5.00 or more in order to keep the site and it\'s services alive!', 'Tenshi'), (8, 'Tenshi', 0, 0, '#EE9400', 'Users that bought premium to help us keep the site and its services alive!', 'Tenshi'),
(9, 'Alumnii', 0, 0, '#FF69B4', 'People who have contributed to the community but have moved on or resigned.', 'Alumnii') (9, 'Alumnii', 0, 0, '#FF69B4', 'People who have contributed to the community but have moved on or resigned.', 'Alumnii'),
ON DUPLICATE KEY UPDATE `id` = VALUES(`id`), `name` = VALUES(`name`), `multi` = VALUES(`multi`), `hidden` = VALUES(`hidden`), `colour` = VALUES(`colour`), `description` = VALUES(`description`), `title` = VALUES(`title`); (10, 'Restricted', 0, 1, '#333', 'Users that are restricted.', 'Restricted');
DROP TABLE IF EXISTS `sakura_regcodes`; DROP TABLE IF EXISTS `sakura_regcodes`;
CREATE TABLE `sakura_regcodes` ( CREATE TABLE `sakura_regcodes` (
@ -458,28 +465,9 @@ CREATE TABLE `sakura_sessions` (
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `userid` (`userid`), KEY `userid` (`userid`),
CONSTRAINT `sakura_sessions_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE CONSTRAINT `sakura_sessions_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `sakura_users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=165 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_sock_perms`;
CREATE TABLE `sakura_sock_perms` (
`rid` bigint(128) unsigned NOT NULL DEFAULT '0' COMMENT 'ID of rank that this permission counts for (set to 0 if user).',
`uid` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'ID of the user this permission counts for (set to 0 if rank).',
`perms` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '1,0,0,0,0,0' COMMENT 'Permission data (has access, in-chat rank, user type, log access, nick access, channel creation)'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO `sakura_sock_perms` (`rid`, `uid`, `perms`) VALUES
(1, 0, '0,0,0,0,0,0'),
(2, 0, '1,0,0,0,0,0'),
(3, 0, '1,3,1,1,1,1'),
(4, 0, '1,4,2,1,1,2'),
(5, 0, '1,2,1,1,1,1'),
(6, 0, '1,0,0,0,0,0'),
(7, 0, '1,2,1,1,1,1'),
(8, 0, '1,1,0,1,1,1'),
(9, 0, '1,1,0,1,1,1')
ON DUPLICATE KEY UPDATE `rid` = VALUES(`rid`), `uid` = VALUES(`uid`), `perms` = VALUES(`perms`);
DROP TABLE IF EXISTS `sakura_topics`; DROP TABLE IF EXISTS `sakura_topics`;
CREATE TABLE `sakura_topics` ( CREATE TABLE `sakura_topics` (
`topic_id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'MySQL Generated ID used for sorting.', `topic_id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'MySQL Generated ID used for sorting.',
@ -496,7 +484,7 @@ CREATE TABLE `sakura_topics` (
PRIMARY KEY (`topic_id`), PRIMARY KEY (`topic_id`),
KEY `forum_id` (`forum_id`), KEY `forum_id` (`forum_id`),
CONSTRAINT `sakura_topics_ibfk_1` FOREIGN KEY (`forum_id`) REFERENCES `sakura_forums` (`forum_id`) ON DELETE CASCADE ON UPDATE CASCADE CONSTRAINT `sakura_topics_ibfk_1` FOREIGN KEY (`forum_id`) REFERENCES `sakura_forums` (`forum_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_users`; DROP TABLE IF EXISTS `sakura_users`;
@ -520,12 +508,12 @@ CREATE TABLE `sakura_users` (
`regdate` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Timestamp of account creation.', `regdate` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Timestamp of account creation.',
`lastdate` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Last time anything was done on this account.', `lastdate` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Last time anything was done on this account.',
`lastunamechange` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Last username change.', `lastunamechange` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Last username change.',
`birthday` varchar(16) COLLATE utf8_bin DEFAULT NULL COMMENT 'Birthdate of the user.', `birthday` date DEFAULT NULL COMMENT 'Birthdate of the user.',
`country` varchar(4) COLLATE utf8_bin NOT NULL COMMENT 'Contains ISO 3166 country code of user''s registration location.', `country` char(2) COLLATE utf8_bin NOT NULL COMMENT 'Contains ISO 3166 country code of user''s registration location.',
`userData` text COLLATE utf8_bin COMMENT 'All additional profile data.', `userData` text COLLATE utf8_bin COMMENT 'All additional profile data.',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `username_clean` (`username_clean`) UNIQUE KEY `username_clean` (`username_clean`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `sakura_warnings`; DROP TABLE IF EXISTS `sakura_warnings`;
@ -544,4 +532,4 @@ CREATE TABLE `sakura_warnings` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-- 2015-08-21 22:06:54 -- 2015-09-05 16:08:34

View file

@ -57,7 +57,8 @@
"20150831", "20150831",
"20150902", "20150902",
"20150903", "20150903",
"20150904" "20150904",
"20150905"
] ]
@ -2456,6 +2457,61 @@
"user": "Flashwave" "user": "Flashwave"
} }
],
"20150905": [
{
"type": "UPD",
"change": "Finished implementation of Urls class.",
"user": "Flashwave"
},
{
"type": "FIX",
"change": "Fully fixed the user numbering bug on the List view.",
"user": "Flashwave"
},
{
"type": "ADD",
"change": "Added a configuration value to change how many users are displayed on the memberlist per page.",
"user": "Flashwave"
},
{
"type": "FIX",
"change": "Made the payment cancelled message look less odd.",
"user": "Flashwave"
},
{
"type": "FIX",
"change": "Fixed out of line padding on info pages.",
"user": "Flashwave"
},
{
"type": "UPD",
"change": "Use Twig Blocks instead of Includes.",
"user": "Flashwave"
},
{
"type": "FIX",
"change": "Fixed parallax disabling not working on Yuuno.",
"user": "Flashwave"
},
{
"type": "UPD",
"change": "Implemented Urls class in PHP files.",
"user": "Flashwave"
},
{
"type": "REM",
"change": "Dropped SockChat class and rely on system permissions from Sock Chat permissions.",
"user": "Flashwave"
},
{
"type": "ADD",
"change": "Implemented IP checking in the session manager.",
"user": "Flashwave"
}
] ]
} }

View file

@ -1,31 +1,31 @@
<?php <?php
/* /*
* Flashii PBKDF2 Password Hashing * Sakura PBKDF2 Password Hashing
* *
* Based on Password Hashing With PBKDF2 (https://defuse.ca/php-pbkdf2.htm). * Based on Password Hashing With PBKDF2 (https://defuse.ca/php-pbkdf2.htm).
* Copyright (c) 2013, Taylor Hornby * Copyright (c) 2013, Taylor Hornby
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */

View file

@ -192,9 +192,12 @@ class Main {
$mail->SetFrom(Configuration::getConfig('smtp_from_email'), Configuration::getConfig('smtp_from_name')); $mail->SetFrom(Configuration::getConfig('smtp_from_email'), Configuration::getConfig('smtp_from_name'));
// Set the addressee // Set the addressee
foreach($to as $email => $name) foreach($to as $email => $name) {
$mail->AddBCC($email, $name); $mail->AddBCC($email, $name);
}
// Subject line // Subject line
$mail->Subject = $subject; $mail->Subject = $subject;
@ -222,9 +225,12 @@ class Main {
$mail->ClearAddresses(); $mail->ClearAddresses();
// If we got an error return the error // If we got an error return the error
if(!$send) if(!$send) {
return $mail->ErrorInfo; return $mail->ErrorInfo;
}
// Else just return whatever // Else just return whatever
return $send; return $send;
@ -239,13 +245,19 @@ class Main {
$string = strip_tags($string); $string = strip_tags($string);
// If set also make the string lowercase // If set also make the string lowercase
if($lower) if($lower){
$string = strtolower($string); $string = strtolower($string);
}
// If set remove all characters that aren't a-z or 0-9 // If set remove all characters that aren't a-z or 0-9
if($nospecial) if($nospecial) {
$string = preg_replace('/[^a-z0-9]/', '', $string); $string = preg_replace('/[^a-z0-9]/', '', $string);
}
// Return clean string // Return clean string
return $string; return $string;
@ -265,9 +277,12 @@ class Main {
$newsPosts[$newsId]['rdata'] = Users::getRank($newsPosts[$newsId]['udata']['rank_main']); $newsPosts[$newsId]['rdata'] = Users::getRank($newsPosts[$newsId]['udata']['rank_main']);
// Check if a custom name colour is set and if so overwrite the rank colour // Check if a custom name colour is set and if so overwrite the rank colour
if($newsPosts[$newsId]['udata']['name_colour'] != null) if($newsPosts[$newsId]['udata']['name_colour'] != null){
$newsPosts[$newsId]['rdata']['colour'] = $newsPosts[$newsId]['udata']['name_colour']; $newsPosts[$newsId]['rdata']['colour'] = $newsPosts[$newsId]['udata']['name_colour'];
}
} }
// Return posts // Return posts
@ -307,13 +322,19 @@ class Main {
if(filter_var($ip, FILTER_VALIDATE_IP)) { if(filter_var($ip, FILTER_VALIDATE_IP)) {
// IPv4 // IPv4
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
return 4; return 4;
}
// IPv6 // IPv6
if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
return 6; return 6;
}
} }
// Not an IP or unknown type // Not an IP or unknown type
@ -334,9 +355,12 @@ class Main {
$binaryIP = null; $binaryIP = null;
// "Build" binary IP // "Build" binary IP
foreach($unpacked as $char) foreach($unpacked as $char) {
$binaryIP .= str_pad(decbin(ord($char)), 8, '0', STR_PAD_LEFT); $binaryIP .= str_pad(decbin(ord($char)), 8, '0', STR_PAD_LEFT);
}
// Return IP // Return IP
return $binaryIP; return $binaryIP;
@ -406,9 +430,12 @@ class Main {
foreach($cfhosts as $subnet) { foreach($cfhosts as $subnet) {
// Return true if found // Return true if found
if(self::matchSubnet($ip, $subnet)) if(self::matchSubnet($ip, $subnet)) {
return true; return true;
}
} }
// Return false if fails // Return false if fails
@ -426,9 +453,12 @@ class Main {
if(self::checkCFIP($ip)) { if(self::checkCFIP($ip)) {
// If it is check if the CloudFlare IP header is set and if it is assign it to the ip variable // If it is check if the CloudFlare IP header is set and if it is assign it to the ip variable
if(isset($_SERVER['HTTP_CF_CONNECTING_IP'])) if(isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
$ip = $_SERVER['HTTP_CF_CONNECTING_IP']; $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
}
} }
// Return the correct IP // Return the correct IP
@ -440,9 +470,12 @@ class Main {
public static function getCountryCode() { public static function getCountryCode() {
// Check if the required header is set and return it // Check if the required header is set and return it
if(isset($_SERVER['HTTP_CF_IPCOUNTRY'])) if(isset($_SERVER['HTTP_CF_IPCOUNTRY'])) {
return $_SERVER['HTTP_CF_IPCOUNTRY']; return $_SERVER['HTTP_CF_IPCOUNTRY'];
}
// Return XX as a fallback // Return XX as a fallback
return 'XX'; return 'XX';
@ -452,9 +485,12 @@ class Main {
public static function newActionCode($action, $userid, $instruct) { public static function newActionCode($action, $userid, $instruct) {
// Make sure the user we're working with exists // Make sure the user we're working with exists
if(Users::getUser($userid)['id'] == 0) if(Users::getUser($userid)['id'] == 0) {
return false; return false;
}
// Convert the instruction array to a JSON // Convert the instruction array to a JSON
$instruct = json_encode($instruct); $instruct = json_encode($instruct);
@ -484,15 +520,21 @@ class Main {
]); ]);
// Check if the code exists // Check if the code exists
if(count($keyRow) <= 1) if(count($keyRow) <= 1) {
return [0, 'INVALID_CODE']; return [0, 'INVALID_CODE'];
}
// Check if the code was intended for the user that's using this code // Check if the code was intended for the user that's using this code
if($keyRow['userid'] != 0) { if($keyRow['userid'] != 0) {
if($keyRow['userid'] != $uid) if($keyRow['userid'] != $uid) {
return [0, 'INVALID_USER']; return [0, 'INVALID_USER'];
}
} }
// Remove the key from the database // Remove the key from the database
@ -523,11 +565,16 @@ class Main {
$iso3166 = json_decode(utf8_encode(file_get_contents(ROOT .'_sakura/'. Configuration::getLocalConfig('data', 'iso3166'))), true); $iso3166 = json_decode(utf8_encode(file_get_contents(ROOT .'_sakura/'. Configuration::getLocalConfig('data', 'iso3166'))), true);
// Check if key exists // Check if key exists
if(array_key_exists($code, $iso3166)) if(array_key_exists($code, $iso3166)) {
return $iso3166[$code]; // If entry found return the full name return $iso3166[$code]; // If entry found return the full name
else
} else {
return 'Unknown'; // Else return unknown return 'Unknown'; // Else return unknown
}
} }
// Get FAQ data // Get FAQ data
@ -548,9 +595,12 @@ class Main {
$return = Database::fetch('logtypes', false, ['id' => [$type, '=']]); $return = Database::fetch('logtypes', false, ['id' => [$type, '=']]);
// Check if type exists and else return a unformattable string // Check if type exists and else return a unformattable string
if(count($return) < 2) if(count($return) < 2) {
return 'Unknown action.'; return 'Unknown action.';
}
// Return the string // Return the string
return $return['string']; return $return['string'];

View file

@ -66,8 +66,7 @@ class Permissions {
// Site management permissions // Site management permissions
'MANAGE' => [ 'MANAGE' => [
'USE_MANAGE' => 1, 'USE_MANAGE' => 1
'EDIT_INFO_PAGES' => 2
] ]
@ -77,19 +76,30 @@ class Permissions {
public static function check($layer, $action, $operator, $mode = 0) { public static function check($layer, $action, $operator, $mode = 0) {
// Check if the permission layer and the permission itself exists // Check if the permission layer and the permission itself exists
if(!array_key_exists($layer, self::$permissions) || !array_key_exists($action, self::$permissions[$layer])) if(!array_key_exists($layer, self::$permissions) || !array_key_exists($action, self::$permissions[$layer])) {
return false; return false;
}
// Convert to the appropiate mode // Convert to the appropiate mode
if($mode === 2) if($mode === 2) {
$operator = self::getRankPermissions($operator)[$layer]; $operator = self::getRankPermissions($operator)[$layer];
elseif($mode === 1)
} elseif($mode === 1) {
$operator = self::getUserPermissions($operator)[$layer]; $operator = self::getUserPermissions($operator)[$layer];
}
// Perform the bitwise AND // Perform the bitwise AND
if(bindec($operator) & self::$permissions[$layer][$action]) if(bindec($operator) & self::$permissions[$layer][$action]) {
return true; return true;
}
// Else just return false // Else just return false
return false; return false;
@ -103,13 +113,19 @@ class Permissions {
$perms = []; $perms = [];
// Get permission row for all ranks // Get permission row for all ranks
foreach($ranks as $rank) foreach($ranks as $rank) {
$getRanks[] = Database::fetch('permissions', false, ['rid' => [$rank, '='], 'uid' => [0 ,'=']]); $getRanks[] = Database::fetch('permissions', false, ['rid' => [$rank, '='], 'uid' => [0 ,'=']]);
}
// Check if getRanks is empty or if the rank id is 0 return the fallback // Check if getRanks is empty or if the rank id is 0 return the fallback
if(empty($getRanks) || in_array(0, $ranks)) if(empty($getRanks) || in_array(0, $ranks)) {
$getRanks = [self::$fallback]; $getRanks = [self::$fallback];
}
// Go over the permission data // Go over the permission data
foreach($getRanks as $rank) { foreach($getRanks as $rank) {
@ -158,24 +174,36 @@ class Permissions {
$rankPerms = self::getRankPermissions(json_decode($user['ranks'], true)); $rankPerms = self::getRankPermissions(json_decode($user['ranks'], true));
// Just return the rank permissions if no special ones are set // Just return the rank permissions if no special ones are set
if(empty($userPerms)) if(empty($userPerms)) {
return $rankPerms; return $rankPerms;
}
// Split the inherit option things up // Split the inherit option things up
$inheritance = str_split($userPerms['rankinherit']); $inheritance = str_split($userPerms['rankinherit']);
// Override site permissions // Override site permissions
if(!$inheritance[0]) if(!$inheritance[0]) {
$rankPerms['SITE'] = $userPerms['siteperms']; $rankPerms['SITE'] = $userPerms['siteperms'];
}
// Override management permissions // Override management permissions
if(!$inheritance[1]) if(!$inheritance[1]) {
$rankPerms['MANAGE'] = $userPerms['manageperms']; $rankPerms['MANAGE'] = $userPerms['manageperms'];
}
// Override forum permissions // Override forum permissions
if(!$inheritance[2]) if(!$inheritance[2]) {
$rankPerms['FORUM'] = $userPerms['forumperms']; $rankPerms['FORUM'] = $userPerms['forumperms'];
}
// Return permissions // Return permissions
return $rankPerms; return $rankPerms;

View file

@ -53,11 +53,16 @@ class Session {
$session = Database::fetch('sessions', true, ['userid' => [$userId, '='], 'skey' => [$sessionId, '=']]); $session = Database::fetch('sessions', true, ['userid' => [$userId, '='], 'skey' => [$sessionId, '=']]);
// Check if we actually got something in return // Check if we actually got something in return
if(!count($session)) if(!count($session)) {
return false; return false;
else
} else {
$session = $session[0]; $session = $session[0];
}
// Check if the session expired // Check if the session expired
if($session['expire'] < time()) { if($session['expire'] < time()) {
@ -69,10 +74,52 @@ class Session {
} }
// Origin checking
if($ipCheck = Configuration::getConfig('session_check')) {
// Split both IPs up
$sessionIP = explode('.', $session['userip']);
$userIP = explode('.', Main::getRemoteIP());
// Take 1 off the ipCheck variable so it's equal to the array keys
$ipCheck = $ipCheck - 1;
// Check if the user's IP is similar to the session's registered IP
switch($ipCheck) {
// 000.xxx.xxx.xxx
case 3:
if($userIP[3] !== $sessionIP[3]) return false;
// xxx.000.xxx.xxx
case 2:
case 3:
if($userIP[2] !== $sessionIP[2]) return false;
// xxx.xxx.000.xxx
case 1:
case 2:
case 3:
if($userIP[1] !== $sessionIP[1]) return false;
// xxx.xxx.xxx.000
case 0:
case 1:
case 2:
case 3:
if($userIP[0] !== $sessionIP[0]) return false;
}
}
// If the remember flag is set extend the session time // If the remember flag is set extend the session time
if($session['remember']) if($session['remember']) {
Database::update('sessions', [['expire' => time() + 604800], ['id' => [$session['id'], '=']]]); Database::update('sessions', [['expire' => time() + 604800], ['id' => [$session['id'], '=']]]);
}
// Return 2 if the remember flag is set and return 1 if not // Return 2 if the remember flag is set and return 1 if not
return $session['remember'] ? 2 : 1; return $session['remember'] ? 2 : 1;
@ -82,9 +129,12 @@ class Session {
public static function deleteSession($sessionId, $key = false) { public static function deleteSession($sessionId, $key = false) {
// Check if the session exists // Check if the session exists
if(!Database::fetch('sessions', [($key ? 'skey' : 'id'), true, [$sessionId, '=']])) if(!Database::fetch('sessions', [($key ? 'skey' : 'id'), true, [$sessionId, '=']])) {
return false; return false;
}
// Run the query // Run the query
Database::delete('sessions', [($key ? 'skey' : 'id') => [$sessionId, '=']]); Database::delete('sessions', [($key ? 'skey' : 'id') => [$sessionId, '=']]);

View file

@ -1,128 +0,0 @@
<?php
/*
* Sock Chat extensions
*/
namespace Sakura;
class SockChat {
// Permission indexes
public static $_PERMS_ACCESS_INDEX = 0;
public static $_PERMS_RANK_INDEX = 1;
public static $_PERMS_TYPE_INDEX = 2;
public static $_PERMS_LOGS_INDEX = 3;
public static $_PERMS_NICK_INDEX = 4;
public static $_PERMS_CHANNEL_INDEX = 5;
// Fallback permission row
public static $_PERMS_FALLBACK = [1, 0, 0, 0, 0, 0];
// Get all permission data
public static function getAllPermissions() {
// Get all data from the permissions table
$perms = Database::fetch('sock_perms');
// Parse permission string
foreach($perms as $id => $perm)
$perms[$id]['perms'] = self::decodePerms($perm['perms']);
// Return the permission data
return $perms;
}
// Get permission data for a specific rank
public static function getRankPermissions($rid) {
// Get data by rank id from permissions table
$perms = Database::fetch('sock_perms', false, ['rid' => [$rid, '='], 'uid' => [0, '=']]);
// Check if we got a row back
if(empty($perms)) {
$perms = [
'rid' => 0,
'uid' => 0,
'perms' => self::$_PERMS_FALLBACK
];
}
// Parse permission string
$perms = self::decodePerms($perms['perms']);
// Return the permission data
return $perms;
}
// Get all rank permission data
public static function getUserPermissions($uid) {
// Get data by user id from permissions table
$perms = Database::fetch('sock_perms', false, ['uid' => [$uid, '='], 'rid' => [0, '=']]);
// Check if we got a row back
if(empty($perms)) {
// If we didn't get the user's rank account row
$user = Users::getUser($uid);
// Then return the data for their rank
return self::getRankPermissions($user['rank_main']);
}
// Parse permission string
$perms = self::decodePerms($perms['perms']);
// Return the permission data
return $perms;
}
// Decode permission string
public static function decodePerms($perms) {
// Explode the commas
$exploded = is_array($perms) ? $perms : explode(',', $perms);
// "Reset" $perms
$perms = array();
// Put the data in the correct order
$perms['access'] = $exploded[ self::$_PERMS_ACCESS_INDEX ];
$perms['rank'] = $exploded[ self::$_PERMS_RANK_INDEX ];
$perms['type'] = $exploded[ self::$_PERMS_TYPE_INDEX ];
$perms['logs'] = $exploded[ self::$_PERMS_LOGS_INDEX ];
$perms['nick'] = $exploded[ self::$_PERMS_NICK_INDEX ];
$perms['channel'] = $exploded[ self::$_PERMS_CHANNEL_INDEX ];
// Return formatted permissions array
return $perms;
}
// Encode permission string
public static function encodePerms($perms) {
// Create array
$encoded = array();
// Put the data in the correct order
$encoded[ self::$_PERMS_ACCESS_INDEX ] = empty($perms['access']) ? 0 : $perms['access'];
$encoded[ self::$_PERMS_RANK_INDEX ] = empty($perms['rank']) ? 0 : $perms['rank'];
$encoded[ self::$_PERMS_TYPE_INDEX ] = empty($perms['type']) ? 0 : $perms['type'];
$encoded[ self::$_PERMS_LOGS_INDEX ] = empty($perms['logs']) ? 0 : $perms['logs'];
$encoded[ self::$_PERMS_NICK_INDEX ] = empty($perms['nick']) ? 0 : $perms['nick'];
$encoded[ self::$_PERMS_CHANNEL_INDEX ] = empty($perms['channel']) ? 0 : $perms['channel'];
// Implode the array
$perms = implode(',', $encoded);
// Return formatted permissions array
return $perms;
}
}

View file

@ -11,20 +11,34 @@ class Urls {
protected $urls = [ protected $urls = [
// General site sections // General site sections
'SITE_HOME' => ['/', '/'], 'SITE_HOME' => ['/', '/'],
'SITE_NEWS' => ['/news.php', '/news'], 'SITE_NEWS' => ['/news.php', '/news'],
'SITE_NEWS_PAGE' => ['/news.php?page=%u', '/news/p%u'], 'SITE_NEWS_PAGE' => ['/news.php?page=%u', '/news/p%u'],
'SITE_NEWS_POST' => ['/news.php?id=%u', '/news/%u'], 'SITE_NEWS_POST' => ['/news.php?id=%u', '/news/%u'],
'SITE_NEWS_RSS' => ['/news.php?xml=true', '/news.xml'], 'SITE_NEWS_RSS' => ['/news.php?xml=true', '/news.xml'],
'SITE_SEARCH' => ['/search.php', '/search'], 'SITE_SEARCH' => ['/search.php', '/search'],
'SITE_MEMBERS' => ['/members.php', '/members'], 'SITE_PREMIUM' => ['/support.php', '/support'],
'SITE_PREMIUM' => ['/support.php', '/support'], 'SITE_DONATE_TRACK' => ['/support.php?tracker=true', '/support/tracker'],
'SITE_FAQ' => ['/faq.php', '/faq'], 'SITE_DONATE_TRACK_PAGE' => ['/support.php?tracker=true&page=%u', '/support/tracker/%u'],
'SITE_LOGIN' => ['/authenticate.php', '/login'], 'SITE_FAQ' => ['/faq.php', '/faq'],
'SITE_REGISTER' => ['/authenticate.php', '/register'], 'SITE_LOGIN' => ['/authenticate.php', '/login'],
'CHANGELOG' => ['/changelog.php', '/changelog'], 'SITE_LOGOUT' => ['/authenticate.php', '/logout'],
'INFO_PAGE' => ['/index.php?p=%s', '/p/%s'], 'SITE_REGISTER' => ['/authenticate.php', '/register'],
'AUTH_ACTION' => ['/authenticate.php', '/authenticate'], 'SITE_FORGOT_PASSWORD' => ['/authenticate.php', '/forgotpassword'],
'SITE_ACTIVATE' => ['/authenticate.php', '/activate'],
'CHANGELOG' => ['/changelog.php', '/changelog'],
'INFO_PAGE' => ['/index.php?p=%s', '/p/%s'],
'AUTH_ACTION' => ['/authenticate.php', '/authenticate'],
// Memberlist
'MEMBERLIST_INDEX' => ['/members.php', '/members'],
'MEMBERLIST_SORT' => ['/members.php?sort=%s', '/members/%s'],
'MEMBERLIST_RANK' => ['/members.php?rank=%u', '/members/%u'],
'MEMBERLIST_PAGE' => ['/members.php?page=%u', '/members/p%u'],
'MEMBERLIST_SORT_RANK' => ['/members.php?sort=%s&rank=%u', '/members/%s/%u'],
'MEMBERLIST_RANK_PAGE' => ['/members.php?rank=%u&page=%u', '/members/%u/p%u'],
'MEMBERLIST_SORT_PAGE' => ['/members.php?sort=%s&page=%u', '/members/%s/p%u'],
'MEMBERLIST_ALL' => ['/members.php?sort=%s&rank=%u&page=%u', '/members/%s/%u/p%u'],
// Forums // Forums
'FORUM_INDEX' => ['/index.php?forum=true', '/forum'], 'FORUM_INDEX' => ['/index.php?forum=true', '/forum'],
@ -44,8 +58,9 @@ class Urls {
// User actions // User actions
'USER_LOGOUT' => ['/authenticate.php?mode=logout&time=%u&session=%s&redirect=%s', '/logout?mode=logout&time=%u&session=%s&redirect=%s'], 'USER_LOGOUT' => ['/authenticate.php?mode=logout&time=%u&session=%s&redirect=%s', '/logout?mode=logout&time=%u&session=%s&redirect=%s'],
'USER_PROFILE' => ['/profile.php?u=%s', '/u/%s'],
'USER_REPORT' => ['/report.php?mode=user&u=%u', '/u/%u/report'], 'USER_REPORT' => ['/report.php?mode=user&u=%u', '/u/%u/report'],
'USER_PROFILE' => ['/profile.php?u=%s', '/u/%s'],
'USER_GROUP' => ['/group.php?g=%u', '/g/%u'],
// Settings urls // Settings urls
'SETTINGS_INDEX' => ['/settings.php', '/settings'], 'SETTINGS_INDEX' => ['/settings.php', '/settings'],
@ -60,7 +75,9 @@ class Urls {
'FRIEND_REMOVE' => ['/settings.php?friend-action=true&remove=%u&session=%s&time=%u&redirect=%s', '/friends?remove=%u&session=%s&time=%u&redirect=%s'], 'FRIEND_REMOVE' => ['/settings.php?friend-action=true&remove=%u&session=%s&time=%u&redirect=%s', '/friends?remove=%u&session=%s&time=%u&redirect=%s'],
// Manage urls // Manage urls
'MANAGE_INDEX' => ['/manage.php', '/manage'] 'MANAGE_INDEX' => ['/manage.php', '/manage'],
'MANAGE_CAT' => ['/manage.php?cat=%s', '/manage/%s'],
'MANAGE_MODE' => ['/manage.php?cat=%s&mode=%s', '/manage/%s/%s']
]; ];

View file

@ -64,19 +64,28 @@ class Users {
if(!$bypassCookies) { if(!$bypassCookies) {
// Check if the cookies are set // Check if the cookies are set
if(!isset($_COOKIE[Configuration::getConfig('cookie_prefix') .'id']) || !isset($_COOKIE[Configuration::getConfig('cookie_prefix') .'session'])) if(!isset($_COOKIE[Configuration::getConfig('cookie_prefix') .'id']) || !isset($_COOKIE[Configuration::getConfig('cookie_prefix') .'session'])) {
return false; return false;
}
} }
// Check if the session exists // Check if the session exists
if(!$session = Session::checkSession($uid, $sid)) if(!$session = Session::checkSession($uid, $sid)) {
return false; return false;
}
// Check if the user is activated // Check if the user is activated
if(Permissions::check('SITE', 'DEACTIVATED', $uid, 1)) if(Permissions::check('SITE', 'DEACTIVATED', $uid, 1)) {
return false; return false;
}
// Extend the cookie times if the remember flag is set // Extend the cookie times if the remember flag is set
if($session == 2 && !$bypassCookies) { if($session == 2 && !$bypassCookies) {
@ -107,13 +116,19 @@ class Users {
public static function login($username, $password, $remember = false, $cookies = true) { public static function login($username, $password, $remember = false, $cookies = true) {
// Check if authentication is disallowed // Check if authentication is disallowed
if(Configuration::getConfig('lock_authentication')) if(Configuration::getConfig('lock_authentication')) {
return [0, 'AUTH_LOCKED']; return [0, 'AUTH_LOCKED'];
}
// Check if the user that's trying to log in actually exists // Check if the user that's trying to log in actually exists
if(!$uid = self::userExists($username, false)) if(!$uid = self::userExists($username, false)) {
return [0, 'USER_NOT_EXIST']; return [0, 'USER_NOT_EXIST'];
}
// Get account data // Get account data
$user = self::getUser($uid); $user = self::getUser($uid);
@ -140,9 +155,12 @@ class Users {
} }
// Check if the user has the required privs to log in // Check if the user has the required privs to log in
if(Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) if(Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
return [0, 'NOT_ALLOWED']; return [0, 'NOT_ALLOWED'];
}
// Create a new session // Create a new session
$sessionKey = Session::newSession($user['id'], $remember); $sessionKey = Session::newSession($user['id'], $remember);
@ -155,7 +173,7 @@ class Users {
} }
// Successful login! (also has a thing for the legacy password system) // Successful login! (also has a thing for the legacy password system)
return [1, ($user['password_algo'] == 'legacy' ? 'LEGACY_SUCCESS' : 'LOGIN_SUCESS')]; return [1, 'LOGIN_SUCESS'];
} }
@ -163,13 +181,19 @@ class Users {
public static function logout() { public static function logout() {
// Check if user is logged in // Check if user is logged in
if(!self::checkLogin()) if(!self::checkLogin()) {
return false; return false;
}
// Remove the active session from the database // Remove the active session from the database
if(!Session::deleteSession(Session::$sessionId, true)) if(!Session::deleteSession(Session::$sessionId, true)) {
return false; return false;
}
// Set cookies // Set cookies
setcookie(Configuration::getConfig('cookie_prefix') .'id', 0, time() - 60, Configuration::getConfig('cookie_path'), Configuration::getConfig('cookie_domain')); setcookie(Configuration::getConfig('cookie_prefix') .'id', 0, time() - 60, Configuration::getConfig('cookie_path'), Configuration::getConfig('cookie_domain'));
setcookie(Configuration::getConfig('cookie_prefix') .'session', '', time() - 60, Configuration::getConfig('cookie_path'), Configuration::getConfig('cookie_domain')); setcookie(Configuration::getConfig('cookie_prefix') .'session', '', time() - 60, Configuration::getConfig('cookie_path'), Configuration::getConfig('cookie_domain'));
@ -183,62 +207,98 @@ class Users {
public static function register($username, $password, $confirmpass, $email, $tos, $captcha = null, $regkey = null) { public static function register($username, $password, $confirmpass, $email, $tos, $captcha = null, $regkey = null) {
// Check if authentication is disallowed // Check if authentication is disallowed
if(Configuration::getConfig('lock_authentication')) if(Configuration::getConfig('lock_authentication')) {
return [0, 'AUTH_LOCKED']; return [0, 'AUTH_LOCKED'];
}
// Check if registration is even enabled // Check if registration is even enabled
if(Configuration::getConfig('disable_registration')) if(Configuration::getConfig('disable_registration')) {
return [0, 'DISABLED']; return [0, 'DISABLED'];
}
// Check if registration codes are required // Check if registration codes are required
if(Configuration::getConfig('require_registration_code')) { if(Configuration::getConfig('require_registration_code')) {
// Check if the code is valid // Check if the code is valid
if(!self::checkRegistrationCode($regkey)) if(!self::checkRegistrationCode($regkey)) {
return [0, 'INVALID_REG_KEY']; return [0, 'INVALID_REG_KEY'];
}
} }
// Check if the user agreed to the ToS // Check if the user agreed to the ToS
if(!$tos) if(!$tos) {
return [0, 'TOS']; return [0, 'TOS'];
}
// Verify the captcha if it's enabled // Verify the captcha if it's enabled
if(Configuration::getConfig('recaptcha')) { if(Configuration::getConfig('recaptcha')) {
if(!Main::verifyCaptcha($captcha)['success']) if(!Main::verifyCaptcha($captcha)['success']) {
return [0, 'CAPTCHA_FAIL']; return [0, 'CAPTCHA_FAIL'];
}
} }
// Check if the username already exists // Check if the username already exists
if(self::userExists($username, false)) if(self::userExists($username, false)) {
return [0, 'USER_EXISTS']; return [0, 'USER_EXISTS'];
}
// Username too short // Username too short
if(strlen($username) < Configuration::getConfig('username_min_length')) if(strlen($username) < Configuration::getConfig('username_min_length')) {
return [0, 'NAME_TOO_SHORT']; return [0, 'NAME_TOO_SHORT'];
}
// Username too long // Username too long
if(strlen($username) > Configuration::getConfig('username_max_length')) if(strlen($username) > Configuration::getConfig('username_max_length')) {
return [0, 'NAME_TOO_LONG']; return [0, 'NAME_TOO_LONG'];
}
// Check if the given email address is formatted properly // Check if the given email address is formatted properly
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return [0, 'INVALID_EMAIL']; return [0, 'INVALID_EMAIL'];
}
// Check the MX record of the email // Check the MX record of the email
if(!Main::checkMXRecord($email)) if(!Main::checkMXRecord($email)) {
return [0, 'INVALID_MX']; return [0, 'INVALID_MX'];
}
// Check password entropy // Check password entropy
if(Main::pwdEntropy($password) < Configuration::getConfig('min_entropy')) if(Main::pwdEntropy($password) < Configuration::getConfig('min_entropy')) {
return [0, 'PASS_TOO_SHIT']; return [0, 'PASS_TOO_SHIT'];
}
// Passwords do not match // Passwords do not match
if($password != $confirmpass) if($password != $confirmpass) {
return [0, 'PASS_NOT_MATCH']; return [0, 'PASS_NOT_MATCH'];
}
// Set a few variables // Set a few variables
$usernameClean = Main::cleanString($username, true); $usernameClean = Main::cleanString($username, true);
$emailClean = Main::cleanString($email, true); $emailClean = Main::cleanString($email, true);
@ -295,9 +355,12 @@ class Users {
public static function sendPasswordForgot($username, $email) { public static function sendPasswordForgot($username, $email) {
// Check if authentication is disallowed // Check if authentication is disallowed
if(Configuration::getConfig('lock_authentication')) if(Configuration::getConfig('lock_authentication')) {
return [0, 'AUTH_LOCKED']; return [0, 'AUTH_LOCKED'];
}
// Clean username string // Clean username string
$usernameClean = Main::cleanString($username, true); $usernameClean = Main::cleanString($username, true);
$emailClean = Main::cleanString($email, true); $emailClean = Main::cleanString($email, true);
@ -309,13 +372,19 @@ class Users {
]); ]);
// Check if user exists // Check if user exists
if(count($user) < 2) if(count($user) < 2) {
return [0, 'USER_NOT_EXIST']; return [0, 'USER_NOT_EXIST'];
}
// Check if the user has the required privs to log in // Check if the user has the required privs to log in
if(Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) if(Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
return [0, 'NOT_ALLOWED']; return [0, 'NOT_ALLOWED'];
}
// Generate the verification key // Generate the verification key
$verk = Main::newActionCode('LOST_PASS', $user['id'], [ $verk = Main::newActionCode('LOST_PASS', $user['id'], [
'meta' => [ 'meta' => [
@ -323,13 +392,16 @@ class Users {
] ]
]); ]);
// Create new urls object
$urls = new Urls();
// Build the e-mail // Build the e-mail
$message = "Hello ". $user['username'] .",\r\n\r\n"; $message = "Hello ". $user['username'] .",\r\n\r\n";
$message .= "You are receiving this notification because you have (or someone pretending to be you has) requested a password reset link to be sent for your account on \"". Configuration::getConfig('sitename') ."\". If you did not request this notification then please ignore it, if you keep receiving it please contact the site administrator.\r\n\r\n"; $message .= "You are receiving this notification because you have (or someone pretending to be you has) requested a password reset link to be sent for your account on \"". Configuration::getConfig('sitename') ."\". If you did not request this notification then please ignore it, if you keep receiving it please contact the site administrator.\r\n\r\n";
$message .= "To use this password reset key you need to go to a special page. To do this click the link provided below.\r\n\r\n"; $message .= "To use this password reset key you need to go to a special page. To do this click the link provided below.\r\n\r\n";
$message .= "http://". Configuration::getConfig('url_main') ."/forgotpassword?pw=true&uid=". $user['id'] ."&key=". $verk ."\r\n\r\n"; $message .= "http://". Configuration::getConfig('url_main') . $urls->format('SITE_FORGOT_PASSWORD') ."?pw=true&uid=". $user['id'] ."&key=". $verk ."\r\n\r\n";
$message .= "If successful you should be able to change your password here.\r\n\r\n"; $message .= "If successful you should be able to change your password here.\r\n\r\n";
$message .= "Alternatively if the above method fails for some reason you can go to http://". Configuration::getConfig('url_main') ."/forgotpassword?pw=true&uid=". $user['id'] ." and use the key listed below:\r\n\r\n"; $message .= "Alternatively if the above method fails for some reason you can go to http://". Configuration::getConfig('url_main') . $urls->format('SITE_FORGOT_PASSWORD') ."?pw=true&uid=". $user['id'] ." and use the key listed below:\r\n\r\n";
$message .= "Verification key: ". $verk ."\r\n\r\n"; $message .= "Verification key: ". $verk ."\r\n\r\n";
$message .= "You can of course change this password yourself via the profile page. If you have any difficulties please contact the site administrator.\r\n\r\n"; $message .= "You can of course change this password yourself via the profile page. If you have any difficulties please contact the site administrator.\r\n\r\n";
$message .= "--\r\n\r\nThanks\r\n\r\n". Configuration::getConfig('mail_signature'); $message .= "--\r\n\r\nThanks\r\n\r\n". Configuration::getConfig('mail_signature');
@ -346,24 +418,36 @@ class Users {
public static function resetPassword($verk, $uid, $newpass, $verpass) { public static function resetPassword($verk, $uid, $newpass, $verpass) {
// Check if authentication is disallowed // Check if authentication is disallowed
if(Configuration::getConfig('lock_authentication')) if(Configuration::getConfig('lock_authentication')) {
return [0, 'AUTH_LOCKED']; return [0, 'AUTH_LOCKED'];
}
// Check password entropy // Check password entropy
if(Main::pwdEntropy($newpass) < Configuration::getConfig('min_entropy')) if(Main::pwdEntropy($newpass) < Configuration::getConfig('min_entropy')) {
return [0, 'PASS_TOO_SHIT']; return [0, 'PASS_TOO_SHIT'];
}
// Passwords do not match // Passwords do not match
if($newpass != $verpass) if($newpass != $verpass) {
return [0, 'PASS_NOT_MATCH']; return [0, 'PASS_NOT_MATCH'];
}
// Check the verification key // Check the verification key
$action = Main::useActionCode('LOST_PASS', $verk, $uid); $action = Main::useActionCode('LOST_PASS', $verk, $uid);
// Check if we got a negative return // Check if we got a negative return
if(!$action[0]) if(!$action[0]) {
return [0, $action[1]]; return [0, $action[1]];
}
// Hash the password // Hash the password
$password = Hashing::create_hash($newpass); $password = Hashing::create_hash($newpass);
$time = time(); $time = time();
@ -391,9 +475,12 @@ class Users {
public static function resendActivationMail($username, $email) { public static function resendActivationMail($username, $email) {
// Check if authentication is disallowed // Check if authentication is disallowed
if(Configuration::getConfig('lock_authentication')) if(Configuration::getConfig('lock_authentication')) {
return [0, 'AUTH_LOCKED']; return [0, 'AUTH_LOCKED'];
}
// Clean username string // Clean username string
$usernameClean = Main::cleanString($username, true); $usernameClean = Main::cleanString($username, true);
$emailClean = Main::cleanString($email, true); $emailClean = Main::cleanString($email, true);
@ -405,13 +492,19 @@ class Users {
]); ]);
// Check if user exists // Check if user exists
if(count($user) < 2) if(count($user) < 2) {
return [0, 'USER_NOT_EXIST']; return [0, 'USER_NOT_EXIST'];
}
// Check if a user is activated // Check if a user is activated
if(!Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) if(!Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
return [0, 'USER_ALREADY_ACTIVE']; return [0, 'USER_ALREADY_ACTIVE'];
}
// Send activation e-mail // Send activation e-mail
self::sendActivationMail($user['id']); self::sendActivationMail($user['id']);
@ -427,9 +520,12 @@ class Users {
$user = Database::fetch('users', false, ['id' => [$uid, '=']]); $user = Database::fetch('users', false, ['id' => [$uid, '=']]);
// User is already activated or doesn't even exist // User is already activated or doesn't even exist
if(count($user) < 2 || !Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) if(count($user) < 2 || !Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
return false; return false;
}
// Generate activation key // Generate activation key
$activate = ($customKey ? $customKey : Main::newActionCode('ACTIVATE', $uid, [ $activate = ($customKey ? $customKey : Main::newActionCode('ACTIVATE', $uid, [
'user' => [ 'user' => [
@ -438,15 +534,18 @@ class Users {
] ]
])); ]));
// Create new urls object
$urls = new Urls();
// Build the e-mail // Build the e-mail
$message = "Welcome to ". Configuration::getConfig('sitename') ."!\r\n\r\n"; $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 .= "Please keep this e-mail for your records. Your account intormation is as follows:\r\n\r\n";
$message .= "----------------------------\r\n\r\n"; $message .= "----------------------------\r\n\r\n";
$message .= "Username: ". $user['username'] ."\r\n\r\n"; $message .= "Username: ". $user['username'] ."\r\n\r\n";
$message .= "Your profile: http://". Configuration::getConfig('url_main') ."/u/". $user['id'] ."\r\n\r\n"; $message .= "Your profile: http://". Configuration::getConfig('url_main') . $urls->format('USER_PROFILE', [$user['id']]) ."\r\n\r\n";
$message .= "----------------------------\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 .= "Please visit the following link in order to activate your account:\r\n\r\n";
$message .= "http://". Configuration::getConfig('url_main') ."/activate?mode=activate&u=". $user['id'] ."&k=". $activate ."\r\n\r\n"; $message .= "http://". Configuration::getConfig('url_main') . $urls->format('SITE_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 .= "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 .= "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 .= "Thank you for registering.\r\n\r\n";
@ -467,13 +566,19 @@ class Users {
$user = Database::fetch('users', false, ['id' => [$uid, '=']]); $user = Database::fetch('users', false, ['id' => [$uid, '=']]);
// Check if user exists // Check if user exists
if(!count($user) > 1) if(!count($user) > 1) {
return [0, 'USER_NOT_EXIST']; return [0, 'USER_NOT_EXIST'];
}
// Check if user is already activated // Check if user is already activated
if(!Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) if(!Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
return [0, 'USER_ALREADY_ACTIVE']; return [0, 'USER_ALREADY_ACTIVE'];
}
// Set default values for activation // Set default values for activation
$rank = 2; $rank = 2;
$ranks = json_encode([2]); $ranks = json_encode([2]);
@ -485,9 +590,12 @@ class Users {
$action = Main::useActionCode('ACTIVATE', $key, $uid); $action = Main::useActionCode('ACTIVATE', $key, $uid);
// Check if we got a negative return // Check if we got a negative return
if(!$action[0]) if(!$action[0]) {
return [0, $action[1]]; return [0, $action[1]];
}
// Assign the special values // Assign the special values
$instructionData = json_decode($action[2], true); $instructionData = json_decode($action[2], true);
$rank = $instructionData['user']['rank_main']; $rank = $instructionData['user']['rank_main'];
@ -518,13 +626,19 @@ class Users {
$user = Database::fetch('users', false, ['id' => [$uid, '=']]); $user = Database::fetch('users', false, ['id' => [$uid, '=']]);
// Check if user exists // Check if user exists
if(!count($user) > 1) if(!count($user) > 1) {
return [0, 'USER_NOT_EXIST']; return [0, 'USER_NOT_EXIST'];
}
// Check if user is already deactivated // Check if user is already deactivated
if(Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) if(Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
return [0, 'USER_ALREADY_DEACTIVE']; return [0, 'USER_ALREADY_DEACTIVE'];
}
// Deactivate the account // Deactivate the account
Database::update('users', [ Database::update('users', [
[ [
@ -556,9 +670,12 @@ class Users {
public static function markRegistrationCodeUsed($code, $uid = 0) { public static function markRegistrationCodeUsed($code, $uid = 0) {
// Check if the code exists // Check if the code exists
if(!$id = self::checkRegistrationCode($code)) if(!$id = self::checkRegistrationCode($code)) {
return false; return false;
}
// Mark it as used // Mark it as used
Database::update('regcodes', [ Database::update('regcodes', [
[ [
@ -579,13 +696,19 @@ class Users {
public static function createRegistrationCode() { public static function createRegistrationCode() {
// Check if we're logged in // Check if we're logged in
if(!self::checkLogin()) if(!self::checkLogin()) {
return false; return false;
}
// Check if the user is not exceeding the maximum registration key amount // 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')) if(count(Database::fetch('regcodes', true, ['uid' => [Session::$userId, '=']])) >= Configuration::getConfig('max_reg_keys')) {
return false; return false;
}
// Generate a code by MD5'ing some random bullshit // Generate a code by MD5'ing some random bullshit
$code = md5('SAKURA'. rand(0, 99999999) . Session::$userId .'NOOKLSISGOD'); $code = md5('SAKURA'. rand(0, 99999999) . Session::$userId .'NOOKLSISGOD');
@ -612,9 +735,12 @@ class Users {
$ranks = json_decode($user['ranks'], true); $ranks = json_decode($user['ranks'], true);
// Check if the rank we're trying to set is actually there // Check if the rank we're trying to set is actually there
if(!in_array($rid, $ranks)) if(!in_array($rid, $ranks)) {
return false; return false;
}
// Update the row // Update the row
Database::update('users', [ Database::update('users', [
[ [
@ -709,9 +835,12 @@ class Users {
$user = $userIdIsUserData ? $userid : self::getUser($userid); $user = $userIdIsUserData ? $userid : self::getUser($userid);
// Check if the main rank is the specified rank // Check if the main rank is the specified rank
if(in_array($user['rank_main'], $ranks)) if(in_array($user['rank_main'], $ranks)) {
return true; return true;
}
// Decode the json for the user's ranks // Decode the json for the user's ranks
$uRanks = json_decode($user['ranks'], true); $uRanks = json_decode($user['ranks'], true);
@ -750,9 +879,12 @@ class Users {
$profileFields = Database::fetch('profilefields'); $profileFields = Database::fetch('profilefields');
// If there's nothing just return null // If there's nothing just return null
if(!count($profileFields)) if(!count($profileFields)) {
return null; return null;
}
// Create output array // Create output array
$fields = []; $fields = [];
@ -811,16 +943,22 @@ class Users {
$profileFields = Database::fetch('profilefields'); $profileFields = Database::fetch('profilefields');
// If there's nothing just return null // If there's nothing just return null
if(!count($profileFields)) if(!count($profileFields)) {
return null; return null;
}
// Assign the profileData variable // Assign the profileData variable
$profileData = ($inputIsData ? $id : self::getUser($id)['userData']); $profileData = ($inputIsData ? $id : self::getUser($id)['userData']);
// Once again if nothing was returned just return null // Once again if nothing was returned just return null
if(count($profileData) < 1 || $profileData == null || empty($profileData['profileFields'])) if(count($profileData) < 1 || $profileData == null || empty($profileData['profileFields'])) {
return null; return null;
}
// Redeclare profileData // Redeclare profileData
$profileData = $profileData['profileFields']; $profileData = $profileData['profileFields'];
@ -834,9 +972,12 @@ class Users {
$fieldName = Main::cleanString($field['name'], true, true); $fieldName = Main::cleanString($field['name'], true, true);
// Check if the user has the current field set otherwise continue // Check if the user has the current field set otherwise continue
if(!array_key_exists($fieldName, $profileData)) if(!array_key_exists($fieldName, $profileData)) {
continue; continue;
}
// Assign field to output with value // Assign field to output with value
$profile[$fieldName] = array(); $profile[$fieldName] = array();
$profile[$fieldName]['name'] = $field['name']; $profile[$fieldName]['name'] = $field['name'];
@ -844,9 +985,12 @@ class Users {
$profile[$fieldName]['islink'] = $field['islink']; $profile[$fieldName]['islink'] = $field['islink'];
// If the field is set to be a link add a value for that as well // If the field is set to be a link add a value for that as well
if($field['islink']) if($field['islink']) {
$profile[$fieldName]['link'] = str_replace('{{ VAL }}', $profileData[$fieldName], $field['linkformat']); $profile[$fieldName]['link'] = str_replace('{{ VAL }}', $profileData[$fieldName], $field['linkformat']);
}
// Check if we have additional options as well // Check if we have additional options as well
if($field['additional'] != null) { if($field['additional'] != null) {
@ -857,9 +1001,12 @@ class Users {
foreach($additional as $subName => $subField) { foreach($additional as $subName => $subField) {
// Check if the user has the current field set otherwise continue // Check if the user has the current field set otherwise continue
if(!array_key_exists($subName, $profileData)) if(!array_key_exists($subName, $profileData)) {
continue; continue;
}
// Assign field to output with value // Assign field to output with value
$profile[$fieldName][$subName] = $profileData[$subName]; $profile[$fieldName][$subName] = $profileData[$subName];
@ -905,9 +1052,12 @@ class Users {
$user = self::getUser($id); $user = self::getUser($id);
// Return false if the user doesn't exist because a user that doesn't exist can't be online // Return false if the user doesn't exist because a user that doesn't exist can't be online
if(empty($user)) if(empty($user)) {
return false; return false;
}
// Return true if the user was online in the last 5 minutes // Return true if the user was online in the last 5 minutes
return ($user['lastdate'] > (time() - 500)); return ($user['lastdate'] > (time() - 500));
@ -979,18 +1129,24 @@ class Users {
public static function checkUserPremium($id) { public static function checkUserPremium($id) {
// Check if the user has static premium // Check if the user has static premium
if(Permissions::check('SITE', 'STATIC_PREMIUM', $id, 1)) if(Permissions::check('SITE', 'STATIC_PREMIUM', $id, 1)) {
return [2, 0, time() + 1]; return [2, 0, time() + 1];
}
// Attempt to retrieve the premium record from the database // Attempt to retrieve the premium record from the database
$getRecord = Database::fetch('premium', false, [ $getRecord = Database::fetch('premium', false, [
'uid' => [$id, '='] 'uid' => [$id, '=']
]); ]);
// If nothing was returned just return false // If nothing was returned just return false
if(empty($getRecord)) if(empty($getRecord)) {
return [0]; return [0];
}
// Check if the Tenshi hasn't expired // Check if the Tenshi hasn't expired
if($getRecord['expiredate'] < time()) { if($getRecord['expiredate'] < time()) {
@ -1021,9 +1177,12 @@ class Users {
self::addRanksToUser([$premiumRank], $id); self::addRanksToUser([$premiumRank], $id);
// Check if the user's default rank is standard user and update it to premium // Check if the user's default rank is standard user and update it to premium
if(self::getUser($id)['rank_main'] == 2) if(self::getUser($id)['rank_main'] == 2) {
self::setDefaultRank($id, $premiumRank); self::setDefaultRank($id, $premiumRank);
}
} elseif($check[0] == 0 && count($check) > 1) { } elseif($check[0] == 0 && count($check) > 1) {
// Else remove the rank from them // Else remove the rank from them
@ -1040,9 +1199,12 @@ class Users {
$user = Database::fetch('users', false, ['id' => [$id, '=']]); $user = Database::fetch('users', false, ['id' => [$id, '=']]);
// Return false if no user was found // Return false if no user was found
if(empty($user)) if(empty($user)) {
$user = self::$emptyUser; $user = self::$emptyUser;
}
// Parse the json in the additional section // Parse the json in the additional section
$user['userData'] = json_decode($user['userData'], true); $user['userData'] = json_decode($user['userData'], true);
@ -1058,9 +1220,12 @@ class Users {
$rank = Database::fetch('ranks', false, ['id' => [$id, '=']]); $rank = Database::fetch('ranks', false, ['id' => [$id, '=']]);
// Return false if no rank was found // Return false if no rank was found
if(empty($rank)) if(empty($rank)) {
return self::$emptyRank; return self::$emptyRank;
}
// If rank was found return rank data // If rank was found return rank data
return $rank; return $rank;
@ -1087,9 +1252,12 @@ class Users {
public static function getUsersInRank($rankId, $users = null, $excludeAbyss = true) { public static function getUsersInRank($rankId, $users = null, $excludeAbyss = true) {
// Get all users (or use the supplied user list to keep server load down) // Get all users (or use the supplied user list to keep server load down)
if(!$users) if(!$users) {
$users = self::getAllUsers(); $users = self::getAllUsers();
}
// Make output array // Make output array
$rank = array(); $rank = array();
@ -1097,9 +1265,12 @@ class Users {
foreach($users as $user) { foreach($users as $user) {
// If so store the user's row in the array // If so store the user's row in the array
if(self::checkIfUserHasRanks([$rankId], $user, true) && ($excludeAbyss ? $user['password_algo'] != 'nologin' : true)) if(self::checkIfUserHasRanks([$rankId], $user, true) && ($excludeAbyss ? $user['password_algo'] != 'nologin' : true)) {
$rank[] = $user; $rank[] = $user;
}
} }
// Then return the array with the user rows // Then return the array with the user rows
@ -1120,13 +1291,19 @@ class Users {
foreach($getUsers as $user) { foreach($getUsers as $user) {
// Skip abyss // Skip abyss
if(!$includeAbyss && $user['password_algo'] == 'nologin') if(!$includeAbyss && $user['password_algo'] == 'nologin') {
continue; continue;
}
// Skip if inactive and not include deactivated users // Skip if inactive and not include deactivated users
if(!$includeInactive && Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) if(!$includeInactive && Permissions::check('SITE', 'DEACTIVATED', $user['id'], 1)) {
continue; continue;
}
$users[$user['id']] = $user; $users[$user['id']] = $user;
} }
@ -1146,9 +1323,12 @@ class Users {
$ranks = []; $ranks = [];
// Reorder shit // Reorder shit
foreach($getRanks as $rank) foreach($getRanks as $rank) {
$ranks[$rank['id']] = $rank; $ranks[$rank['id']] = $rank;
}
// and return an array with the ranks // and return an array with the ranks
return $ranks; return $ranks;
@ -1173,11 +1353,19 @@ class Users {
// Prepare conditions // Prepare conditions
$conditions = array(); $conditions = array();
$conditions['uid'] = [($uid ? $uid : Session::$userId), '=']; $conditions['uid'] = [($uid ? $uid : Session::$userId), '='];
if($timediff)
if($timediff) {
$conditions['timestamp'] = [time() - $timediff, '>']; $conditions['timestamp'] = [time() - $timediff, '>'];
if($excludeRead)
}
if($excludeRead) {
$conditions['notif_read'] = [0, '=']; $conditions['notif_read'] = [0, '='];
}
// Get notifications for the database // Get notifications for the database
$notifications = Database::fetch('notifications', true, $conditions); $notifications = Database::fetch('notifications', true, $conditions);
@ -1188,9 +1376,12 @@ class Users {
foreach($notifications as $notification) { foreach($notifications as $notification) {
// If the notifcation is already read skip // If the notifcation is already read skip
if($notification['notif_read']) if($notification['notif_read']) {
continue; continue;
}
// Mark them as read // Mark them as read
self::markNotificationRead($notification['id']); self::markNotificationRead($notification['id']);
@ -1273,9 +1464,12 @@ class Users {
public static function getFriends($uid = null, $timestamps = false, $getData = false, $checkOnline = false) { public static function getFriends($uid = null, $timestamps = false, $getData = false, $checkOnline = false) {
// Assign $uid // Assign $uid
if(!$uid) if(!$uid) {
$uid = Session::$userId; $uid = Session::$userId;
}
// Get all friends // Get all friends
$getFriends = Database::fetch('friends', true, [ $getFriends = Database::fetch('friends', true, [
'uid' => [$uid, '='] 'uid' => [$uid, '=']
@ -1318,9 +1512,12 @@ class Users {
public static function getPendingFriends($uid = null, $getData = false) { public static function getPendingFriends($uid = null, $getData = false) {
// Assign $of automatically if it's not set // Assign $of automatically if it's not set
if(!$uid) if(!$uid) {
$uid = Session::$userId; $uid = Session::$userId;
}
// Get all friend entries from other people involved the current user // Get all friend entries from other people involved the current user
$friends = Database::fetch('friends', true, [ $friends = Database::fetch('friends', true, [
'fid' => [$uid, '='] 'fid' => [$uid, '=']
@ -1355,23 +1552,32 @@ class Users {
public static function checkFriend($fid, $uid = null) { public static function checkFriend($fid, $uid = null) {
// Assign $uid // Assign $uid
if(!$uid) if(!$uid) {
$uid = Session::$userId; $uid = Session::$userId;
}
// Get the user's friends // Get the user's friends
$self = self::getFriends($uid); $self = self::getFriends($uid);
// Check if the friend is actually in the user's array // Check if the friend is actually in the user's array
if(!in_array($fid, $self)) if(!in_array($fid, $self)) {
return 0; return 0;
}
// Get the friend's friends // Get the friend's friends
$friend = self::getFriends($fid); $friend = self::getFriends($fid);
// Check if the friend is actually in the user's array // Check if the friend is actually in the user's array
if(in_array($uid, $friend)) if(in_array($uid, $friend)) {
return 2; return 2;
}
// Return true if all went through // Return true if all went through
return 1; return 1;
@ -1381,13 +1587,19 @@ class Users {
public static function addFriend($uid) { public static function addFriend($uid) {
// Validate that the user exists // Validate that the user exists
if(!self::getUser($uid)) if(!self::getUser($uid)) {
return [0, 'USER_NOT_EXIST']; return [0, 'USER_NOT_EXIST'];
}
// Check if the user already has this user a friend // Check if the user already has this user a friend
if(Database::fetch('friends', false, ['fid' => [$uid, '='], 'uid' => [Session::$userId, '=']])) if(Database::fetch('friends', false, ['fid' => [$uid, '='], 'uid' => [Session::$userId, '=']])) {
return [0, 'ALREADY_FRIENDS']; return [0, 'ALREADY_FRIENDS'];
}
// Add friend // Add friend
Database::insert('friends', [ Database::insert('friends', [
'uid' => Session::$userId, 'uid' => Session::$userId,
@ -1404,9 +1616,12 @@ class Users {
public static function removeFriend($uid, $deleteRequest = false) { public static function removeFriend($uid, $deleteRequest = false) {
// Check if the user has this user a friend // Check if the user has this user a friend
if(!Database::fetch('friends', false, ['fid' => [$uid, '='], 'uid' => [Session::$userId, '=']])) if(!Database::fetch('friends', false, ['fid' => [$uid, '='], 'uid' => [Session::$userId, '=']])) {
return [0, 'ALREADY_REMOVED']; return [0, 'ALREADY_REMOVED'];
}
// Remove friend // Remove friend
Database::delete('friends', [ Database::delete('friends', [
'uid' => [Session::$userId, '='], 'uid' => [Session::$userId, '='],

View file

@ -8,7 +8,7 @@
namespace Sakura; namespace Sakura;
// Define Sakura version // Define Sakura version
define('SAKURA_VERSION', '20150903'); define('SAKURA_VERSION', '20150905');
define('SAKURA_VLABEL', 'Eminence'); define('SAKURA_VLABEL', 'Eminence');
define('SAKURA_COLOUR', '#6C3082'); define('SAKURA_COLOUR', '#6C3082');
define('SAKURA_STABLE', false); define('SAKURA_STABLE', false);
@ -48,7 +48,6 @@ require_once ROOT .'_sakura/components/Manage.php';
require_once ROOT .'_sakura/components/Bans.php'; require_once ROOT .'_sakura/components/Bans.php';
require_once ROOT .'_sakura/components/Whois.php'; require_once ROOT .'_sakura/components/Whois.php';
require_once ROOT .'_sakura/components/Payments.php'; require_once ROOT .'_sakura/components/Payments.php';
require_once ROOT .'_sakura/components/SockChat.php';
// Include database extensions // Include database extensions
foreach(glob(ROOT .'_sakura/components/database/*.php') as $driver) { foreach(glob(ROOT .'_sakura/components/database/*.php') as $driver) {
@ -144,10 +143,7 @@ if(!defined('SAKURA_NO_TPL')) {
'requireActivation' => Configuration::getConfig('require_activation'), 'requireActivation' => Configuration::getConfig('require_activation'),
'minPwdEntropy' => Configuration::getConfig('min_entropy'), 'minPwdEntropy' => Configuration::getConfig('min_entropy'),
'minUsernameLength' => Configuration::getConfig('username_min_length'), 'minUsernameLength' => Configuration::getConfig('username_min_length'),
'maxUsernameLength' => Configuration::getConfig('username_max_length'), 'maxUsernameLength' => Configuration::getConfig('username_max_length')
'disqus_shortname' => Configuration::getConfig('disqus_shortname'),
'disqus_api_key' => Configuration::getConfig('disqus_api_key')
], ],
@ -189,7 +185,7 @@ if(!defined('SAKURA_NO_TPL')) {
]); ]);
Users::logout(); Users::logout();
print Templates::render('errors/banned.tpl', $renderData); print Templates::render('main/banned.tpl', $renderData);
exit; exit;
} }

View file

@ -1,8 +0,0 @@
{% include 'global/header.tpl' %}
<div class="content standalone">
<h1>Information</h1>
<hr class="default" />
{{ page.message }}
{% if page.redirect %}<br /><a href="{{ page.redirect }}" class="default">Click here if you aren't being redirected.</a>{% endif %}
</div>
{% include 'global/footer.tpl' %}

View file

@ -1,4 +1,6 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content homepage forum"> <div class="content homepage forum">
<div class="content-right content-column"> <div class="content-right content-column">
{% include 'elements/indexPanel.tpl' %} {% include 'elements/indexPanel.tpl' %}
@ -9,4 +11,4 @@
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<script type="text/javascript" src="{{ sakura.resources }}/js/ybabstat.js"></script> <script type="text/javascript" src="{{ sakura.resources }}/js/ybabstat.js"></script>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,4 +1,6 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content"> <div class="content">
<div class="content-column forum posting"> <div class="content-column forum posting">
<form method="post" action="{{ sakura.currentPage }}"> <form method="post" action="{{ sakura.currentPage }}">
@ -57,4 +59,4 @@
</form> </form>
</div> </div>
</div> </div>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,7 +1,9 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content homepage forum viewforum"> <div class="content homepage forum viewforum">
<div class="content-column"> <div class="content-column">
{% include 'forum/forum.tpl' %} {% include 'forum/forum.tpl' %}
</div> </div>
</div> </div>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,4 +1,6 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content homepage forum viewtopic"> <div class="content homepage forum viewtopic">
<div class="content-column"> <div class="content-column">
<div class="head">{{ forum.forum.forum_name }} / {{ topic.topic_title }}</div> <div class="head">{{ forum.forum.forum_name }} / {{ topic.topic_title }}</div>
@ -56,4 +58,4 @@
{% include 'forum/forumBtns.tpl' %} {% include 'forum/forumBtns.tpl' %}
</div> </div>
</div> </div>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,41 +0,0 @@
<a id="gotop" class="fa fa-angle-double-up hidden" href="#top"></a>
{% if not sakura.versionInfo.stable %}
<div style="background: repeating-linear-gradient(-45deg, #000, #000 10px, #FF0 10px, #FF0 20px); text-align: center; color: #FFF; box-shadow: 0px 0px 1em #FF0;">
<div style="background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .9) 10%, rgba(0, 0, 0, .9) 90%, rgba(0, 0, 0, 0) 100%); display: inline-block; padding: 0 40px;">
<h3><a style="color: inherit; text-decoration: none;" href="{{ urls.format('CHANGELOG') }}#r{{ sakura.versionInfo.version }}" target="_blank">Sakura Revision {{ sakura.versionInfo.version }} Development</a></h1>
</div>
</div>
{% endif %}
</div>
<div class="footer">
<div class="ftsections">
<div class="copycentre">&copy; 2013-2015 <a href="//flash.moe/" target="_blank">Flashwave</a>, et al.</div>
<ul class="ftsection">
<li class="fthead">General</li>
<li><a href="{{ urls.format('SITE_HOME') }}" title="Flashii Frontpage">Home</a></li>
<li><a href="{{ urls.format('SITE_NEWS') }}" title="Flashii News &amp; Updates">News</a></li>
<li><a href="{{ urls.format('SITE_SEARCH') }}" title="Do full-site search requests">Search</a></li>
<li><a href="{{ urls.format('INFO_PAGE', ['contact']) }}" title="Contact our Staff">Contact</a></li>
<li><a href="{{ urls.format('CHANGELOG') }}" title="All the changes made to Sakura are listed here">Changelog</a></li>
<li><a href="{{ urls.format('SITE_PREMIUM') }}" title="Get Tenshi and help us pay the bills">Support us</a></li>
</ul>
<ul class="ftsection">
<li class="fthead">Community</li>
<li><a href="{{ urls.format('FORUM_INDEX') }}" title="Read and post on our forums">Forums</a></li>
<li><a href="https://twitter.com/_flashii" target="_blank" title="Follow us on Twitter for news messages that are too short for the news page">Twitter</a></li>
<li><a href="https://youtube.com/user/flashiinet" target="_blank" title="Our YouTube page where stuff barely ever gets uploaded, mainly used to archive community creations">YouTube</a></li>
<li><a href="https://steamcommunity.com/groups/flashiinet" target="_blank" title="Our Steam group, play games with other members on the site">Steam</a></li>
<li><a href="https://bitbucket.org/circlestorm" target="_blank" title="Our Open Source repository thing">BitBucket</a></li>
</ul>
<ul class="ftsection">
<li class="fthead">Information</li>
<li><a href="{{ urls.format('SITE_FAQ') }}" title="Questions that get Asked Frequently but not actually">FAQ</a></li>
<li><a href="{{ urls.format('INFO_PAGE', ['rules']) }}" title="Some Rules and Information kind of summing up the ToS">Rules</a></li>
<li><a href="//fiistat.us" target="_blank" title="Check the status on our Servers and related services">Server Status</a></li>
<li><a href="{{ urls.format('INFO_PAGE', ['terms']) }}" title="Our Terms of Service">Terms of Service</a></li>
</ul>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,12 @@
{% extends 'global/master.tpl' %}
{% block content %}
<div class="content standalone">
<div>
<h1>Information</h1>
<hr class="default" />
{{ page.message }}
{% if page.redirect %}<br /><a href="{{ page.redirect }}" class="default">Click here if you aren't being redirected.</a>{% endif %}
</div>
</div>
{% endblock %}

View file

@ -10,9 +10,9 @@
<meta name="msapplication-TileColor" content="#fbeeff" /> <meta name="msapplication-TileColor" content="#fbeeff" />
<meta name="msapplication-TileImage" content="/content/images/icons/ms-icon-144x144.png" /> <meta name="msapplication-TileImage" content="/content/images/icons/ms-icon-144x144.png" />
<meta name="theme-color" content="#9475B2" /> <meta name="theme-color" content="#9475B2" />
{% if page.redirect %} {% if page.redirect %}
<meta http-equiv="refresh" content="3; URL={{ page.redirect }}" /> <meta http-equiv="refresh" content="3; URL={{ page.redirect }}" />
{% endif %} {% endif %}
<link rel="apple-touch-icon" sizes="57x57" href="/content/images/icons/apple-icon-57x57.png" /> <link rel="apple-touch-icon" sizes="57x57" href="/content/images/icons/apple-icon-57x57.png" />
<link rel="apple-touch-icon" sizes="60x60" href="/content/images/icons/apple-icon-60x60.png" /> <link rel="apple-touch-icon" sizes="60x60" href="/content/images/icons/apple-icon-60x60.png" />
<link rel="apple-touch-icon" sizes="72x72" href="/content/images/icons/apple-icon-72x72.png" /> <link rel="apple-touch-icon" sizes="72x72" href="/content/images/icons/apple-icon-72x72.png" />
@ -27,19 +27,10 @@
<link rel="icon" type="image/png" sizes="96x96" href="/content/images/icons/favicon-96x96.png" /> <link rel="icon" type="image/png" sizes="96x96" href="/content/images/icons/favicon-96x96.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/content/images/icons/favicon-16x16.png" /> <link rel="icon" type="image/png" sizes="16x16" href="/content/images/icons/favicon-16x16.png" />
<link rel="manifest" href="/manifest.json" /> <link rel="manifest" href="/manifest.json" />
{{ block('meta') }}
<!-- CSS --> <!-- CSS -->
<link rel="stylesheet" type="text/css" href="{{ sakura.resources }}/css/yuuno.css" /> <link rel="stylesheet" type="text/css" href="{{ sakura.resources }}/css/yuuno.css" />
{% if page.style %} {{ block('css') }}
<style type="text/css">
{% for element,properties in page.style %}
{{ element|raw }} {
{% for property,value in properties %}
{{ property|raw }}: {{ value|raw }};
{% endfor %}
}
{% endfor %}
</style>
{% endif %}
<!-- JS --> <!-- JS -->
<script type="text/javascript" src="{{ sakura.resources }}/js/yuuno.js"></script> <script type="text/javascript" src="{{ sakura.resources }}/js/yuuno.js"></script>
<script type="text/javascript"> <script type="text/javascript">
@ -67,45 +58,45 @@
}; };
// Space for things that need to happen onload // Space for things that need to happen onload
window.addEventListener("load", function() { window.addEventListener("load", function() {
// Alter the go to top button // Alter the go to top button
var gotop = document.getElementById('gotop'); var gotop = document.getElementById('gotop');
gotop.setAttribute('href', 'javascript:void(0);'); gotop.setAttribute('href', 'javascript:void(0);');
gotop.setAttribute('onclick', 'scrollToTop();'); gotop.setAttribute('onclick', 'scrollToTop();');
{% if session.checkLogin %} {% if session.checkLogin %}
// Convert href to object in logout link // Convert href to object in logout link
prepareAjaxLink('headerLogoutLink', 'submitPost', ', true, "Logging out..."'); prepareAjaxLink('headerLogoutLink', 'submitPost', ', true, "Logging out..."');
{% elseif not sakura.lockAuth and php.self != '/authenticate.php' %} {% elseif not sakura.lockAuth and php.self != '/authenticate.php' %}
// Make the header login form dynamic // Make the header login form dynamic
var headerLoginForm = document.getElementById('headerLoginForm'); var headerLoginForm = document.getElementById('headerLoginForm');
var createInput = document.createElement('input'); var createInput = document.createElement('input');
var submit = headerLoginForm.querySelector('[type="submit"]'); var submit = headerLoginForm.querySelector('[type="submit"]');
createInput.setAttribute('name', 'ajax'); createInput.setAttribute('name', 'ajax');
createInput.setAttribute('value', 'true'); createInput.setAttribute('value', 'true');
createInput.setAttribute('type', 'hidden'); createInput.setAttribute('type', 'hidden');
headerLoginForm.appendChild(createInput); headerLoginForm.appendChild(createInput);
submit.setAttribute('type', 'button'); submit.setAttribute('type', 'button');
submit.setAttribute('onclick', 'submitPost(\''+ headerLoginForm.action +'\', formToObject(\'headerLoginForm\'), true, \'Logging in...\');'); submit.setAttribute('onclick', 'submitPost(\''+ headerLoginForm.action +'\', formToObject(\'headerLoginForm\'), true, \'Logging in...\');');
{% endif %} {% endif %}
{% if session.checkLogin %} {% if session.checkLogin %}
// Make notification requests (there's a seperate one to make it happen before the first 60 seconds) // Make notification requests (there's a seperate one to make it happen before the first 60 seconds)
notifyRequest('{{ php.sessionid }}');
// Create interval
setInterval(function() {
notifyRequest('{{ php.sessionid }}'); notifyRequest('{{ php.sessionid }}');
}, 60000);
// Create interval
setInterval(function() {
notifyRequest('{{ php.sessionid }}');
}, 60000);
{% endif %} {% endif %}
{% if php.self == '/profile.php' and session.checkLogin and user.data.id != profile.user.id %} {% if php.self == '/profile.php' and session.checkLogin and user.data.id != profile.user.id %}
// Make friend button dynamic // Make friend button dynamic
prepareAjaxLink('profileFriendToggle', 'submitPost', ', true, "{% if profile.friend == 0 %}Adding{% else %}Removing{% endif %} friend..."'); prepareAjaxLink('profileFriendToggle', 'submitPost', ', true, "{% if profile.friend == 0 %}Adding{% else %}Removing{% endif %} friend..."');
{% endif %} {% endif %}
{% if php.self == '/viewtopic.php' and session.checkLogin %} {% if php.self == '/viewtopic.php' and session.checkLogin %}
@ -117,42 +108,52 @@
{% endif %} {% endif %}
{% if php.self == '/authenticate.php' and not sakura.lockAuth %} {% if php.self == '/authenticate.php' and not sakura.lockAuth %}
// AJAX Form Submission
var forms = {
{% if not auth.changingPass %}
"loginForm": 'Logging in...',
{% if not sakura.disableRegistration %}"registerForm": 'Processing registration...',{% endif %}
{% if not sakura.requireActivation %}"resendForm": 'Attempting to resend activation...',{% endif %}
"passwordForm": 'Sending password recovery mail...'
{% else %}
"passwordForm": 'Changing password...'
{% endif %}
};
for(var i in forms) { // AJAX Form Submission
var form = document.getElementById(i); var forms = {
var submit = form.querySelector('[type="submit"]'); {% if not auth.changingPass %}
"loginForm": 'Logging in...',
{% if not sakura.disableRegistration %}
"registerForm": 'Processing registration...',
{% endif %}
{% if not sakura.requireActivation %}
"resendForm": 'Attempting to resend activation...',
{% endif %}
"passwordForm": 'Sending password recovery mail...'
{% else %}
"passwordForm": 'Changing password...'
{% endif %}
};
form.setAttribute('onkeydown', 'formEnterCatch(event, \''+ submit.id +'\');'); for(var i in forms) {
var form = document.getElementById(i);
var submit = form.querySelector('[type="submit"]');
submit.setAttribute('href', 'javascript:void(0);'); form.setAttribute('onkeydown', 'formEnterCatch(event, \''+ submit.id +'\');');
submit.setAttribute('onclick', 'submitPost(\''+ form.action +'\', formToObject(\''+ i+ '\'), true, \''+ forms[i] +'\', '+ (i == 'registerForm' ? 'true' : 'false') +');');
submit.setAttribute('type', 'button'); submit.setAttribute('href', 'javascript:void(0);');
submit.setAttribute('onclick', 'submitPost(\''+ form.action +'\', formToObject(\''+ i+ '\'), true, \''+ forms[i] +'\', '+ (i == 'registerForm' ? 'true' : 'false') +');');
submit.setAttribute('type', 'button');
var createInput = document.createElement('input');
createInput.setAttribute('name', 'ajax');
createInput.setAttribute('value', 'true');
createInput.setAttribute('type', 'hidden');
form.appendChild(createInput);
}
var createInput = document.createElement('input');
createInput.setAttribute('name', 'ajax');
createInput.setAttribute('value', 'true');
createInput.setAttribute('type', 'hidden');
form.appendChild(createInput);
}
{% endif %} {% endif %}
{% if php.self == '/profile.php' ? profile.data.userData.profileBackground : (user.checkPermission('SITE', 'CREATE_BACKGROUND') and user.data.userData.userOptions.profileBackgroundSiteWide and user.data.userData.profileBackground) %} {% if php.self == '/profile.php' ? (profile.data.userData.profileBackground and not profile.data.userData.userOptions.disableProfileParallax) : (user.checkPermission('SITE', 'CREATE_BACKGROUND') and user.data.userData.userOptions.profileBackgroundSiteWide and user.data.userData.profileBackground and not user.data.userData.userOptions.disableProfileParallax) %}
initialiseParallax('userBackground'); initialiseParallax('userBackground');
{% endif %} {% endif %}
}); });
</script> </script>
{{ block('js') }}
</head> </head>
<body> <body>
<div id="container"> <div id="container">
@ -168,7 +169,7 @@
<a class="menu-item fa-list" href="{{ urls.format('FORUM_INDEX') }}" title="Forums"></a> <a class="menu-item fa-list" href="{{ urls.format('FORUM_INDEX') }}" title="Forums"></a>
<a class="menu-item fa-search" href="{{ urls.format('SITE_SEARCH') }}" title="Search"></a> <a class="menu-item fa-search" href="{{ urls.format('SITE_SEARCH') }}" title="Search"></a>
{% if session.checkLogin %} {% if session.checkLogin %}
<a class="menu-item fa-users" href="{{ urls.format('SITE_MEMBERS') }}" title="Members"></a> <a class="menu-item fa-users" href="{{ urls.format('MEMBERLIST_INDEX') }}" title="Members"></a>
<a class="menu-item fa-heart" href="{{ urls.format('SITE_PREMIUM') }}" title="Support us"></a> <a class="menu-item fa-heart" href="{{ urls.format('SITE_PREMIUM') }}" title="Support us"></a>
{% endif %} {% endif %}
</div> </div>
@ -182,9 +183,9 @@
<a class="menu-item fa-sign-out" href="{{ urls.format('USER_LOGOUT', [php.time, php.sessionid, sakura.currentPage]) }}" title="Logout" id="headerLogoutLink"></a> <a class="menu-item fa-sign-out" href="{{ urls.format('USER_LOGOUT', [php.time, php.sessionid, sakura.currentPage]) }}" title="Logout" id="headerLogoutLink"></a>
{% else %} {% else %}
{% 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-sign-in" href="{{ urls.format('SITE_LOGIN') }}" title="Login"></a> <a class="menu-item fa-sign-in" href="{{ urls.format('SITE_LOGIN') }}" title="Login"></a>
{% endif %} {% endif %}
{% endif %} {% endif %}
</div> </div>
@ -220,14 +221,60 @@
</form> </form>
{% endif %} {% endif %}
{% if user.checkPermission('SITE', 'RESTRICTED') %} {% if user.checkPermission('SITE', 'RESTRICTED') %}
<div class="headerNotify" style="padding-top: 10px; padding-bottom: 10px; background: repeating-linear-gradient(-45deg, #B33, #B33 10px, #B00 10px, #B00 20px); text-align: center; color: #FFF; border: 1px solid #C00; box-shadow: 0px 0px 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: 0px 0px 3px #C00;">
<h1>Your account is current in <span style="font-width: 700 !important;">restricted mode</span>!</h1> <h1>Your account is current in <span style="font-width: 700 !important;">restricted mode</span>!</h1>
<div>A staff member has set your account to restricted mode most likely due to violation of the rules. While restricted you won't be able to use most public features of the site. If you think this is a mistake please <a href="{{ urls.format('INFO_PAGE', ['contact']) }}" style="color: inherit;">get in touch with one of our staff members</a>.</div> <div>A staff member has set your account to restricted mode most likely due to violation of the rules. While restricted you won't be able to use most public features of the site. If you think this is a mistake please <a href="{{ urls.format('INFO_PAGE', ['contact']) }}" style="color: inherit;">get in touch with one of our staff members</a>.</div>
</div> </div>
{% endif %} {% endif %}
<noscript> <noscript>
<div class="headerNotify" style="padding-top: 10px; padding-bottom: 10px; background: repeating-linear-gradient(-45deg, #C2AFFE, #C2AFFE 10px, #D3BFFF 10px, #D3BFFF 20px);"> <div class="headerNotify">
<h1>You have JavaScript disabled!</h1> <h1>You have JavaScript disabled!</h1>
<p style="padding: 0 10px;">A lot of things on this site require JavaScript to be enabled (e.g. the chat), we try to keep both sides happy but it is highly recommended that you enable it (you'll also have to deal with this message being here if you don't enable it).</p> <p style="padding: 0 10px;">A lot of things on this site require JavaScript to be enabled (e.g. the chat), we try to keep both sides happy but it is highly recommended that you enable it (you'll also have to deal with this message being here if you don't enable it).</p>
</div> </div>
</noscript> </noscript>
{% block content %}
<h1 class="stylised" style="text-align: center; margin: 2em auto;">{{ php.self }} is now printing!</h1>
{% endblock %}
<a id="gotop" class="fa fa-angle-double-up hidden" href="#top"></a>
{% if not sakura.versionInfo.stable %}
<div style="background: repeating-linear-gradient(-45deg, #000, #000 10px, #FF0 10px, #FF0 20px); text-align: center; color: #FFF; box-shadow: 0px 0px 1em #FF0;">
<div style="background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .9) 10%, rgba(0, 0, 0, .9) 90%, rgba(0, 0, 0, 0) 100%); display: inline-block; padding: 0 40px;">
<h3><a style="color: inherit; text-decoration: none;" href="{{ urls.format('CHANGELOG') }}#r{{ sakura.versionInfo.version }}" target="_blank">Sakura Revision {{ sakura.versionInfo.version }} Development</a></h1>
</div>
</div>
{% endif %}
</div>
<div class="footer">
<div class="ftsections">
<div class="copycentre">&copy; 2013-2015 <a href="//flash.moe/" target="_blank">Flashwave</a>, <a href="http://circlestorm.net/">et al</a>.</div>
<ul class="ftsection">
<li class="fthead">General</li>
<li><a href="{{ urls.format('SITE_HOME') }}" title="Flashii Frontpage">Home</a></li>
<li><a href="{{ urls.format('SITE_NEWS') }}" title="Flashii News &amp; Updates">News</a></li>
<li><a href="{{ urls.format('SITE_SEARCH') }}" title="Do full-site search requests">Search</a></li>
<li><a href="{{ urls.format('INFO_PAGE', ['contact']) }}" title="Contact our Staff">Contact</a></li>
<li><a href="{{ urls.format('CHANGELOG') }}" title="All the changes made to Sakura are listed here">Changelog</a></li>
<li><a href="{{ urls.format('SITE_PREMIUM') }}" title="Get Tenshi and help us pay the bills">Support us</a></li>
</ul>
<ul class="ftsection">
<li class="fthead">Community</li>
<li><a href="{{ urls.format('FORUM_INDEX') }}" title="Read and post on our forums">Forums</a></li>
<li><a href="https://twitter.com/_flashii" target="_blank" title="Follow us on Twitter for news messages that are too short for the news page">Twitter</a></li>
<li><a href="https://youtube.com/user/flashiinet" target="_blank" title="Our YouTube page where stuff barely ever gets uploaded, mainly used to archive community creations">YouTube</a></li>
<li><a href="https://steamcommunity.com/groups/flashiinet" target="_blank" title="Our Steam group, play games with other members on the site">Steam</a></li>
<li><a href="https://bitbucket.org/circlestorm" target="_blank" title="Our Open Source repository thing">BitBucket</a></li>
</ul>
<ul class="ftsection">
<li class="fthead">Information</li>
<li><a href="{{ urls.format('SITE_FAQ') }}" title="Questions that get Asked Frequently but not actually">FAQ</a></li>
<li><a href="{{ urls.format('INFO_PAGE', ['rules']) }}" title="Some Rules and Information kind of summing up the ToS">Rules</a></li>
<li><a href="//fiistat.us" target="_blank" title="Check the status on our Servers and related services">Server Status</a></li>
<li><a href="{{ urls.format('INFO_PAGE', ['terms']) }}" title="Our Terms of Service">Terms of Service</a></li>
</ul>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1 @@
{% extends 'global/master.tpl' %}

View file

@ -1,4 +1,6 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
{% if sakura.lockAuth %} {% if sakura.lockAuth %}
<h1 class="stylised" style="line-height: 1.8em; text-align: center;">Authentication is currently disallowed, try again later.</h1> <h1 class="stylised" style="line-height: 1.8em; text-align: center;">Authentication is currently disallowed, try again later.</h1>
{% else %} {% else %}
@ -190,4 +192,4 @@
<div class="clear"></div> <div class="clear"></div>
</div> </div>
{% endif %} {% endif %}
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,4 +1,6 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content"> <div class="content">
<div class="content-column news banned"> <div class="content-column news banned">
<div style="padding: 20px;"> <div style="padding: 20px;">
@ -23,4 +25,4 @@
</div> </div>
</div> </div>
</div> </div>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,4 +1,6 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content settings"> <div class="content settings">
<div class="content-right content-column"> <div class="content-right content-column">
<div class="head"> <div class="head">
@ -21,4 +23,4 @@
</div> </div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,4 +1,6 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content news settings"> <div class="content news settings">
<div class="head">Forgot Password</div> <div class="head">Forgot Password</div>
<form method="post" action="{{ urls.format('AUTH_ACTION') }}" id="passwordForm"> <form method="post" action="{{ urls.format('AUTH_ACTION') }}" id="passwordForm">
@ -23,4 +25,4 @@
</div> </div>
</form> </form>
</div> </div>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,4 +1,6 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content homepage"> <div class="content homepage">
<div class="content-right content-column"> <div class="content-right content-column">
{% include 'elements/indexPanel.tpl' %} {% include 'elements/indexPanel.tpl' %}
@ -12,4 +14,4 @@
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<script type="text/javascript" src="{{ sakura.resources }}/js/ybabstat.js"></script> <script type="text/javascript" src="{{ sakura.resources }}/js/ybabstat.js"></script>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,5 +1,7 @@
{% include 'global/header.tpl' %} {% include 'global/header.tpl' %}
<div class="content standalone markdown"> <div class="content standalone markdown">
{{ page.content|raw }} <div>
{{ page.content|raw }}
</div>
</div> </div>
{% include 'global/footer.tpl' %} {% include 'global/footer.tpl' %}

View file

@ -1,4 +1,6 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
{% if session.checkLogin %} {% if session.checkLogin %}
<div class="headerNotify" style="padding: 10px 0; margin-bottom: 1px;"> <div class="headerNotify" style="padding: 10px 0; margin-bottom: 1px;">
<h1 style="text-shadow: 0px 0px 5px #555;{% if page.active %} color: {{ page.ranks[page.active].colour }};{% endif %}">{% if not page.active %}All members{% else %}{{ page.ranks[page.active].name }}{% if page.ranks[page.active].multi %}s{% endif %}{% endif %}</h1> <h1 style="text-shadow: 0px 0px 5px #555;{% if page.active %} color: {{ page.ranks[page.active].colour }};{% endif %}">{% if not page.active %}All members{% else %}{{ page.ranks[page.active].name }}{% if page.ranks[page.active].multi %}s{% endif %}{% endif %}</h1>
@ -7,20 +9,20 @@
<div class="membersPage" style="min-height: 500px;"> <div class="membersPage" style="min-height: 500px;">
<div class="dropDown" style="margin: 0px auto; font-size: 1.5em; line-height: 1.5em; height: 30px;"> <div class="dropDown" style="margin: 0px auto; font-size: 1.5em; line-height: 1.5em; height: 30px;">
<div class="dropDownInner" style="float: left; color: #FFF;"> <div class="dropDownInner" style="float: left; color: #FFF;">
<a class="dropDownDesc">Rank:</a><!-- <a class="dropDownDesc">Rank:</a>
--><a href="/members/{% if page.sort != page.sorts[0] %}{{ page.sort }}/{% endif %}"{% if not page.active %} class="dropDownSelected"{% endif %}>All members</a><!-- <a href="{% if page.page and page.sort %}{{ urls.format('MEMBERLIST_SORT_PAGE', [page.sort, (page.page + 1)]) }}{% elseif page.sort %}{{ urls.format('MEMBERLIST_SORT', [page.sort]) }}{% elseif page.page %}{{ urls.format('MEMBERLIST_PAGE', [(page.page + 1)]) }}{% else %}{{ urls.format('MEMBERLIST_INDEX') }}{% endif %}"{% if not page.active %} class="dropDownSelected"{% endif %}>All members</a>
{% for rank in page.ranks %} {% for rank in page.ranks %}
{% if not rank.hidden or (rank.hidden and page.active == rank.id) %} {% if not rank.hidden or (rank.hidden and page.active == rank.id) %}
--><a href="/members/{% if page.sort != page.sorts[0] %}{{ page.sort }}/{% endif %}{{ rank.id }}/" style="color: {{ rank.colour }};"{% if page.active == rank.id %} class="dropDownSelected"{% endif %}>{{ rank.name }}{% if rank.multi %}s{% endif %}</a><!-- <a href="{% if page.sort %}{{ urls.format('MEMBERLIST_SORT_RANK', [page.sort, rank.id]) }}{% else %}{{ urls.format('MEMBERLIST_RANK', [rank.id]) }}{% endif %}" style="color: {{ rank.colour }};"{% if page.active == rank.id %} class="dropDownSelected"{% endif %}>{{ rank.name }}{% if rank.multi %}s{% endif %}</a>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
--></div> </div>
<div class="dropDownInner" style="float: left;"><!-- <div class="dropDownInner" style="float: left;">
--><a class="dropDownDesc">View:</a><!-- <a class="dropDownDesc">View:</a>
{% for sort in page.sorts %} {% for sort in page.sorts %}
--><a href="/members/{{ sort }}/{% if page.active %}{{ page.active }}/{% endif %}{% if page.page %}p{{ page.page + 1 }}/{% endif %}"{% if page.sort == sort %} class="dropDownSelected"{% endif %}>{{ sort|capitalize }}</a><!-- <a href="{% if page.active and page.page %}{{ urls.format('MEMBERLIST_ALL', [sort, page.active, (page.page + 1)]) }}{% elseif page.active %}{{ urls.format('MEMBERLIST_SORT_RANK', [sort, page.active]) }}{% elseif page.page %}{{ urls.format('MEMBERLIST_SORT_PAGE', [sort, (page.page + 1)]) }}{% else %}{{ urls.format('MEMBERLIST_SORT', [sort]) }}{% endif %}"{% if page.sort == sort %} class="dropDownSelected"{% endif %}>{{ sort|capitalize }}</a>
{% endfor %} {% endfor %}
--></div> </div>
</div> </div>
{% if page.notfound %} {% if page.notfound %}
<h1 class="stylised" style="margin-top: 20px;">The requested rank was not found!</h1> <h1 class="stylised" style="margin-top: 20px;">The requested rank was not found!</h1>
@ -52,10 +54,10 @@
<tbody> <tbody>
<tr> <tr>
<td> <td>
#{{ count }} #{{ page.active ? count + 1 : count }}
</td> </td>
<td> <td>
<a href="/u/{{ user.id }}" class="default" style="font-weight: bold; color: {{ page.ranks[user.rank_main].colour }};">{{ user.username }}</a> <a href="{{ urls.format('USER_PROFILE', [user.id]) }}" class="default" style="font-weight: bold; color: {{ page.ranks[user.rank_main].colour }};">{{ user.username }}</a>
</td> </td>
<td> <td>
{{ user.regdate|date(sakura.dateFormat) }} {{ user.regdate|date(sakura.dateFormat) }}
@ -67,7 +69,7 @@
{% if not user.usertitle %}<i>{{ page.ranks[user.rank_main].title }}</i>{% else %}{{ user.usertitle }}{% endif %} {% if not user.usertitle %}<i>{{ page.ranks[user.rank_main].title }}</i>{% else %}{{ user.usertitle }}{% endif %}
</td> </td>
<td> <td>
<img src="{{ sakura.contentPath }}/images/flags/{% if user.country|lower == 'eu' %}europeanunion{% else %}{{ user.country|lower }}{% endif %}.png" alt="{% if user.country|lower == 'eu' %}?{% else %}{{ user.country }}{% endif %}" /> <img src="{{ sakura.contentPath }}/images/flags/{{ user.country|lower }}.png" alt="{% if user.country|lower == 'eu' %}?{% else %}{{ user.country }}{% endif %}" />
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -75,9 +77,9 @@
</table> </table>
{% else %} {% else %}
{% for user in page.users[page.page] %} {% for user in page.users[page.page] %}
<a href="/u/{{ user.id }}">{# These comment tags are here to prevent the link extending too far <a href="{{ urls.format('USER_PROFILE', [user.id]) }}">{# These comment tags are here to prevent the link extending too far
#}<div class="userBox" id="u{{ user.id }}">{# #}<div class="userBox" id="u{{ user.id }}">{#
#}<img src="{{ sakura.contentPath }}/pixel.png" alt="{{ user.username }}" style="background: url('/a/{{ user.id }}') no-repeat center / contain;" />{# #}<img src="{{ sakura.contentPath }}/pixel.png" alt="{{ user.username }}" style="background: url('{{ urls.format('IMAGE_AVATAR', [user.id]) }}') no-repeat center / contain;" />{#
#}<span class="userBoxUserName"{% if page.sort == page.sorts[1] %} style="color: {{ page.ranks[user.rank_main].colour }};"{% endif %}>{# #}<span class="userBoxUserName"{% if page.sort == page.sorts[1] %} style="color: {{ page.ranks[user.rank_main].colour }};"{% endif %}>{#
#}{{ user.username }}{# #}{{ user.username }}{#
#}</span>{# #}</span>{#
@ -90,13 +92,13 @@
{% if page.users|length > 1 %} {% if page.users|length > 1 %}
<div class="pagination"> <div class="pagination">
{% if page.page > 0 %} {% if page.page > 0 %}
<a href="/members/{% if page.sort != page.sorts[0] %}{{ page.sort }}/{% endif %}{% if page.active %}{{ page.active }}/{% endif %}p{{ page.page }}"><span class="fa fa-step-backward"></span></a> <a href="{% if page.sort and page.active %}{{ urls.format('MEMBERLIST_ALL', [page.sort, page.active, page.page]) }}{% elseif page.sort %}{{ urls.format('MEMBERLIST_SORT_PAGE', [page.sort, page.page]) }}{% elseif page.active %}{{ urls.format('MEMBERLIST_RANK_PAGE', [page.active, page.page]) }}{% else %}{{ urls.format('MEMBERLIST_PAGE', [page.page]) }}{% endif %}"><span class="fa fa-step-backward"></span></a>
{% endif %} {% endif %}
{% for count,navpage in page.users %} {% for count,navpage in page.users %}
<a href="/members/{% if page.sort != page.sorts[0] %}{{ page.sort }}/{% endif %}{% if page.active %}{{ page.active }}/{% endif %}p{{ count + 1 }}"{% if count == page.page %} class="current"{% endif %}>{{ count + 1 }}</a> <a href="{% if page.sort and page.active %}{{ urls.format('MEMBERLIST_ALL', [page.sort, page.active, (count + 1)]) }}{% elseif page.sort %}{{ urls.format('MEMBERLIST_SORT_PAGE', [page.sort, (count + 1)]) }}{% elseif page.active %}{{ urls.format('MEMBERLIST_RANK_PAGE', [page.active, (count + 1)]) }}{% else %}{{ urls.format('MEMBERLIST_PAGE', [(count + 1)]) }}{% endif %}"{% if count == page.page %} class="current"{% endif %}>{{ count + 1 }}</a>
{% endfor %} {% endfor %}
{% if page.page + 1 < page.users|length %} {% if page.page + 1 < page.users|length %}
<a href="/members/{% if page.sort != page.sorts[0] %}{{ page.sort }}/{% endif %}{% if page.active %}{{ page.active }}/{% endif %}p{{ page.page + 2 }}"><span class="fa fa-step-forward"></span></a> <a href="{% if page.sort and page.active %}{{ urls.format('MEMBERLIST_ALL', [page.sort, page.active, (page.page + 2)]) }}{% elseif page.sort %}{{ urls.format('MEMBERLIST_SORT_PAGE', [page.sort, (page.page + 2)]) }}{% elseif page.active %}{{ urls.format('MEMBERLIST_RANK_PAGE', [page.active, (page.page + 2)]) }}{% else %}{{ urls.format('MEMBERLIST_PAGE', [(page.page + 2)]) }}{% endif %}"><span class="fa fa-step-forward"></span></a>
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}
@ -104,4 +106,4 @@
{% else %} {% else %}
{% include 'elements/restricted.tpl' %} {% include 'elements/restricted.tpl' %}
{% endif %} {% endif %}
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,7 +1,9 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content"> <div class="content">
<div class="content-column news"> <div class="content-column news">
<div class="head">{% if page.view_post %}{{ newsPosts[0].title }}{% elseif newsPosts|length < 1 %}Post does not exist!{% else %}News <a href="/news.xml" class="fa fa-rss news-rss default"></a>{% endif %}</div> <div class="head">{% if page.view_post %}{{ newsPosts[0].title }}{% elseif newsPosts|length < 1 %}Post does not exist!{% else %}News <a href="{{ urls.format('SITE_NEWS_RSS') }}" class="fa fa-rss news-rss default"></a>{% endif %}</div>
{% if newsPosts|length >= 1 %} {% if newsPosts|length >= 1 %}
{% if page.view_post %} {% if page.view_post %}
{% for newsPost in newsPosts %} {% for newsPost in newsPosts %}
@ -16,13 +18,13 @@
<div> <div>
<div class="pagination" style="float: right;"> <div class="pagination" style="float: right;">
{% if page.currentPage > 0 %} {% if page.currentPage > 0 %}
<a href="/news/p{{ page.currentPage }}"><span class="fa fa-step-backward"></span></a> <a href="{{ urls.format('SITE_NEWS_PAGE', [page.currentPage]) }}"><span class="fa fa-step-backward"></span></a>
{% endif %} {% endif %}
{% for id,npage in newsPosts %} {% for id,npage in newsPosts %}
<a href="/news/p{{ id + 1 }}"{% if id == page.currentPage %} class="current"{% endif %}>{{ id + 1 }}</a> <a href="{{ urls.format('SITE_NEWS_PAGE', [(id + 1)]) }}"{% if id == page.currentPage %} class="current"{% endif %}>{{ id + 1 }}</a>
{% endfor %} {% endfor %}
{% if page.currentPage + 1 < newsPosts|length %} {% if page.currentPage + 1 < newsPosts|length %}
<a href="/news/p{{ page.currentPage + 2 }}"><span class="fa fa-step-forward"></span></a> <a href="{{ urls.format('SITE_NEWS_PAGE', [(page.currentPage + 2)]) }}"><span class="fa fa-step-forward"></span></a>
{% endif %} {% endif %}
</div> </div>
<div class="clear"></div> <div class="clear"></div>
@ -40,4 +42,4 @@
{% endif %} {% endif %}
</div> </div>
</div> </div>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,7 +1,9 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content standalone" style="text-align: center;"> <div class="content standalone" style="text-align: center;">
<h1 class="stylised" style="margin: 1em auto;">Thank you for your contribution!</h1> <h1 class="stylised" style="margin: 1em auto;">Thank you for your contribution!</h1>
<h1 class="fa fa-heart stylised" style="font-size: 20em;"></h1> <h1 class="fa fa-heart stylised" style="font-size: 20em;"></h1>
<h3>Your Tenshi will expire on {{ page.expiration|date(sakura.dateFormat) }}.</h3> <h3>Your Tenshi will expire on {{ page.expiration|date(sakura.dateFormat) }}.</h3>
</div> </div>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -0,0 +1 @@
{% extends 'global/master.tpl' %}

View file

@ -1,4 +1,6 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content" style="background: #FFF;"> <div class="content" style="background: #FFF;">
<div class="content-column news"> <div class="content-column news">
<div class="head">Search</div> <div class="head">Search</div>
@ -17,4 +19,4 @@
<gcse:searchresults></gcse:searchresults> <gcse:searchresults></gcse:searchresults>
</div> </div>
</div> </div>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,4 +1,6 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content settings messages"> <div class="content settings messages">
<div class="content-right content-column"> <div class="content-right content-column">
{% include 'elements/settingsNav.tpl' %} {% include 'elements/settingsNav.tpl' %}
@ -16,4 +18,4 @@
</div> </div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,15 +1,17 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
{% if page.fail %} {% if page.fail %}
<div class="headerNotify"> <div class="headerNotify">
<h1>The payment failed or was cancelled!</h1> <h1>The payment failed or was cancelled!</h1>
<p>Something went wrong while processing the transaction, your PayPal account wasn't charged.</p> <p>Something went wrong while processing the transaction, your PayPal account wasn't charged.</p>
</div> </div>
{% endif %} {% endif %}
<div class="content support"> <div class="content support">
<div class="head">Support {{ sakura.siteName }}</div> <div class="head">Support {{ sakura.siteName }}</div>
<div style="font-size: .9em; margin-bottom: 10px;"> <div style="font-size: .9em; margin-bottom: 10px;">
<p>In order to keep the site, its services and improvements on it going I need money but I'm not that big of a fan of asking for money without giving anything special in return thus Tenshi exists. Tenshi is the name for our supporter rank which gives you access to an extra set of features (which are listed further down on this page). With your help we can keep adding new stuff, get new hardware and keep the site awesome!</p> <p>In order to keep the site, its services and improvements on it going I need money but I'm not that big of a fan of asking for money without giving anything special in return thus Tenshi exists. Tenshi is the name for our supporter rank which gives you access to an extra set of features (which are listed further down on this page). With your help we can keep adding new stuff, get new hardware and keep the site awesome!</p>
<h3><a href="/support/tracker" class="default">Ever wonder what happens on the financial side of things? View the donation tracker!</a></h3> <h3><a href="{{ urls.format('SITE_DONATE_TRACK') }}" class="default">Ever wonder what happens on the financial side of things? View the donation tracker!</a></h3>
</div> </div>
{% if page.current[0] %} {% if page.current[0] %}
<div class="sectionHeader"> <div class="sectionHeader">
@ -105,7 +107,7 @@
{% endif %} {% endif %}
</div> </div>
{% if session.checkLogin and user.checkPermission('SITE', 'OBTAIN_PREMIUM') %} {% if session.checkLogin and user.checkPermission('SITE', 'OBTAIN_PREMIUM') %}
<form action="/support" method="post" id="purchaseForm" class="hidden"> <form action="{{ urls.format('SITE_PREMIUM') }}" method="post" id="purchaseForm" class="hidden">
<input type="hidden" name="mode" value="purchase" /> <input type="hidden" name="mode" value="purchase" />
<input type="hidden" name="time" value="{{ php.time }}" /> <input type="hidden" name="time" value="{{ php.time }}" />
<input type="hidden" name="session" value="{{ php.sessionid }}" /> <input type="hidden" name="session" value="{{ php.sessionid }}" />
@ -115,4 +117,4 @@
window.onload = function() { document.getElementById('totalAmount').innerHTML = ({{ page.price }}).formatMoney(2); }; window.onload = function() { document.getElementById('totalAmount').innerHTML = ({{ page.price }}).formatMoney(2); };
</script> </script>
{% endif %} {% endif %}
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,4 +1,6 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
<div class="content support"> <div class="content support">
<div class="head">Donation Tracker</div> <div class="head">Donation Tracker</div>
<h1 class="stylised" style="margin: 1em auto; text-align: center;">Our current overall balance is &#8364;{{ page.premiumData.balance|number_format(2) }}</h1> <h1 class="stylised" style="margin: 1em auto; text-align: center;">Our current overall balance is &#8364;{{ page.premiumData.balance|number_format(2) }}</h1>
@ -36,7 +38,7 @@
{% for supporter in page.premiumTable[page.currentPage] %} {% for supporter in page.premiumTable[page.currentPage] %}
<tr> <tr>
<td> <td>
<a href="/u/{{ page.premiumData.users[supporter.uid].data.id }}" class="default" style="color: {{ page.premiumData.users[supporter.uid].colour }}; text-shadow: 0 0 7px {% if page.premiumData.users[supporter.uid].colour != 'inherit' %}{{ page.premiumData.users[supporter.uid].colour }}{% else %}#222{% endif %};">{{ page.premiumData.users[supporter.uid].data.username }}</a> <a href="{{ urls.format('USER_PROFILE', [page.premiumData.users[supporter.uid].data.id]) }}" class="default" style="color: {{ page.premiumData.users[supporter.uid].colour }}; text-shadow: 0 0 7px {% if page.premiumData.users[supporter.uid].colour != 'inherit' %}{{ page.premiumData.users[supporter.uid].colour }}{% else %}#222{% endif %};">{{ page.premiumData.users[supporter.uid].data.username }}</a>
</td> </td>
<td style="color: {% if supporter.amount > 0 %}#0A0{% else %}#A00{% endif %};"> <td style="color: {% if supporter.amount > 0 %}#0A0{% else %}#A00{% endif %};">
&#8364;{{ supporter.amount|number_format(2) }} &#8364;{{ supporter.amount|number_format(2) }}
@ -51,16 +53,16 @@
{% if page.premiumTable|length > 1 %} {% if page.premiumTable|length > 1 %}
<div class="pagination" style="float: right;"> <div class="pagination" style="float: right;">
{% if page.currentPage > 0 %} {% if page.currentPage > 0 %}
<a href="/support/tracker/{{ page.currentPage }}"><span class="fa fa-step-backward"></span></a> <a href="{{ urls.format('SITE_DONATE_TRACK_PAGE', [page.currentPage]) }}"><span class="fa fa-step-backward"></span></a>
{% endif %} {% endif %}
{% for count,navpage in page.premiumTable %} {% for count,navpage in page.premiumTable %}
<a href="/support/tracker/{{ count + 1 }}"{% if count == page.currentPage %} class="current"{% endif %}>{{ count + 1 }}</a> <a href="{{ urls.format('SITE_DONATE_TRACK_PAGE', [(count + 1)]) }}"{% if count == page.currentPage %} class="current"{% endif %}>{{ count + 1 }}</a>
{% endfor %} {% endfor %}
{% if page.currentPage + 1 < page.premiumTable|length %} {% if page.currentPage + 1 < page.premiumTable|length %}
<a href="/support/tracker/{{ page.currentPage + 2 }}"><span class="fa fa-step-forward"></span></a> <a href="{{ urls.format('SITE_DONATE_TRACK_PAGE', [(page.currentPage + 2)]) }}"><span class="fa fa-step-forward"></span></a>
{% endif %} {% endif %}
</div> </div>
<div class="clear"></div> <div class="clear"></div>
{% endif %} {% endif %}
</div> </div>
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -1,11 +1,13 @@
{% include 'global/header.tpl' %} {% extends 'global/master.tpl' %}
{% block content %}
{% if profile.checkPermission('SITE', 'DEACTIVATED') or profile.data.password_algo == 'nologin' or (profile.checkPermission('SITE', 'RESTRICTED') and (user.data.id != profile.data.id and not user.checkPermission('MANAGE', 'USE_MANAGE'))) %} {% if profile.checkPermission('SITE', 'DEACTIVATED') or profile.data.password_algo == 'nologin' or (profile.checkPermission('SITE', 'RESTRICTED') and (user.data.id != profile.data.id and not user.checkPermission('MANAGE', 'USE_MANAGE'))) %}
<div class="content standalone" style="padding: 20px;"> <div class="content standalone" style="padding: 20px;">
<h1>The requested user does not exist!</h1> <h1>The requested user does not exist!</h1>
There are a few possible reasons for this: There are a few possible reasons for this:
<ul style="padding-left: 40px;"> <ul style="padding-left: 40px;">
<li>They changed their username.</li> <li>They changed their username.</li>
<li>They may have been <a href="/faq#abyss" class="default">abyss'd</a>.</li> <li>They may have been <a href="{{ urls.format('SITE_FAQ') }}#abyss" class="default">abyss'd</a>.</li>
<li>You made a typo.</li> <li>You made a typo.</li>
<li>They never existed.</li> <li>They never existed.</li>
</ul> </ul>
@ -14,19 +16,19 @@
<div class="content profile"> <div class="content profile">
<div class="{% if profile.userPage|length > 1 %}content-right {% endif %}content-column"> <div class="{% if profile.userPage|length > 1 %}content-right {% endif %}content-column">
<div style="text-align: center;"> <div style="text-align: center;">
<img src="/a/{{ profile.data.id }}" alt="{{ profile.data.username }}'s Avatar" class="default-avatar-setting" style="box-shadow: 0 3px 7px #{% if profile.checkOnline %}484{% else %}844{% endif %};" /><br /> <img src="{{ urls.format('IMAGE_AVATAR', [profile.data.id]) }}" alt="{{ profile.data.username }}'s Avatar" class="default-avatar-setting" style="box-shadow: 0 3px 7px #{% if profile.checkOnline %}484{% else %}844{% endif %};" /><br />
{% if profile.data.rank_main > 1 and profile.checkBan|length < 1 %} {% if profile.data.rank_main > 1 and profile.checkBan|length < 1 %}
<span style="font-size: .8em;">{{ profile.userTitle }}</span> <span style="font-size: .8em;">{{ profile.userTitle }}</span>
<h1 style="color: {{ profile.colour }}; text-shadow: 0 0 7px {% if profile.colour != 'inherit' %}{{ profile.colour }}{% else %}#222{% endif %}; padding: 0 0 2px;">{{ profile.data.username }}</h1> <h1 style="color: {{ profile.colour }}; text-shadow: 0 0 7px {% if profile.colour != 'inherit' %}{{ profile.colour }}{% else %}#222{% endif %}; padding: 0 0 2px;">{{ profile.data.username }}</h1>
{% if profile.checkPremium[0] %}<img src="{{ sakura.contentPath }}/images/tenshi.png" alt="Tenshi" /> {% endif %}<img src="{{ sakura.contentPath }}/images/flags/{% if profile.country.short|lower == 'eu' %}europeanunion{% else %}{{ profile.country.short|lower }}{% endif %}.png" alt="{{ profile.country.short }}" /> <span style="font-size: .9em; line-height: 11px;">{{ profile.country.long }}</span> {% if profile.checkPremium[0] %}<img src="{{ sakura.contentPath }}/images/tenshi.png" alt="Tenshi" /> {% endif %}<img src="{{ sakura.contentPath }}/images/flags/{{ profile.country.short|lower }}.png" alt="{{ profile.country.short }}" /> <span style="font-size: .9em; line-height: 11px;">{{ profile.country.long }}</span>
{% if session.checkLogin %} {% if session.checkLogin %}
<div class="user-actions"> <div class="user-actions">
{% if user.data.id == profile.data.id %} {% if user.data.id == profile.data.id %}
<a class="fa fa-pencil-square-o" title="Edit your profile" href="/settings/profile"></a> <a class="fa fa-pencil-square-o" title="Edit your profile" href="{{ urls.format('SETTING_MODE', ['general', 'profile']) }}"></a>
{% else %} {% else %}
{% if profile.checkFriends(user.data.id) != 0 %}<a class="fa fa-{% if profile.checkFriends(user.data.id) == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>{% endif %} {% if profile.checkFriends(user.data.id) != 0 %}<a class="fa fa-{% if profile.checkFriends(user.data.id) == 2 %}heart{% else %}star{% endif %}" title="You are friends"></a>{% endif %}
<a class="fa fa-user-{% if profile.checkFriends(user.data.id) == 0 %}plus{% else %}times{% endif %}" title="{% if profile.checkFriends(user.data.id) == 0 %}Add {{ legacyprofile.data.username }} as a friend{% else %}Remove friend{% endif %}" href="/friends?{% if profile.checkFriends(user.data.id) == 0 %}add{% else %}remove{% endif %}={{ profile.data.id }}&amp;session={{ php.sessionid }}&amp;time={{ php.time }}&amp;redirect={{ sakura.currentPage }}" id="profileFriendToggle"></a> <a class="fa fa-user-{% if profile.checkFriends(user.data.id) == 0 %}plus{% else %}times{% endif %}" title="{% if profile.checkFriends(user.data.id) == 0 %}Add {{ legacyprofile.data.username }} as a friend{% else %}Remove friend{% endif %}" href="{% if profile.checkFriends(user.data.id) == 0 %}{{ urls.format('FRIEND_ADD', [profile.data.id, php.sessionid, php.time, sakura.currentPage]) }}{% else %}{{ urls.format('FRIEND_REMOVE', [profile.data.id, php.sessionid, php.time, sakura.currentPage]) }}{% endif %}" id="profileFriendToggle"></a>
<a class="fa fa-flag" title="Report {{ profile.data.username }}" href="/u/{{ profile.data.id }}/report"></a> <a class="fa fa-flag" title="Report {{ profile.data.username }}" href="{{ urls.format('USER_REPORT', [profile.data.id]) }}"></a>
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}
@ -96,4 +98,4 @@
<div class="clear"></div> <div class="clear"></div>
</div> </div>
{% endif %} {% endif %}
{% include 'global/footer.tpl' %} {% endblock %}

View file

@ -14,8 +14,6 @@ RewriteBase /
Options +FollowSymLinks -Indexes Options +FollowSymLinks -Indexes
# Rewrite Rules # Rewrite Rules
RewriteRule ^feedback/?$ https://github.com/circlestorm/Sakura/issues [L,QSA]
RewriteRule ^credits/?$ credits.php [L,QSA]
RewriteRule ^index/?$ index.php [L,QSA] RewriteRule ^index/?$ index.php [L,QSA]
RewriteRule ^login/?$|^logout/?$|^activate/?$|^register/?$|^forgotpassword/?|^authenticate/?$ authenticate.php [L,QSA] RewriteRule ^login/?$|^logout/?$|^activate/?$|^register/?$|^forgotpassword/?|^authenticate/?$ authenticate.php [L,QSA]
RewriteRule ^support/?$ support.php [L,QSA] RewriteRule ^support/?$ support.php [L,QSA]
@ -82,5 +80,5 @@ RewriteRule ^forum/post/([0-9]+)/(quote|reply)/?$ posting.php?p=$1&quote=$1 [L,Q
# Management # Management
RewriteRule ^manage/?$ manage.php [L,QSA] RewriteRule ^manage/?$ manage.php [L,QSA]
RewriteRule ^manage/([a-z\-]+)/?$ manage.php?page=$1&sub=0 [L,QSA] RewriteRule ^manage/([a-z\-]+)/?$ manage.php?cat=$1&mode=0 [L,QSA]
RewriteRule ^manage/([a-z\-]+)/([a-z\-]+)/?$ manage.php?page=$1&sub=$2 [L,QSA] RewriteRule ^manage/([a-z\-]+)/([a-z\-]+)/?$ manage.php?cat=$1&mode=$2 [L,QSA]

View file

@ -13,4 +13,4 @@ require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) .'_sakura/sak
header('HTTP/1.0 404 Not Found'); header('HTTP/1.0 404 Not Found');
// Print page contents // Print page contents
print Templates::render('errors/http404.tpl', $renderData); print Templates::render('global/notfound.tpl', $renderData);

View file

@ -23,7 +23,7 @@ if(isset($_REQUEST['mode'])) {
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Action failed', 'title' => 'Action failed',
'redirect' => '/authenticate', 'redirect' => $urls->format('AUTH_ACTION'),
'message' => 'Timestamps differ too much, refresh the page and try again.', 'message' => 'Timestamps differ too much, refresh the page and try again.',
'success' => 0 'success' => 0
]; ];
@ -38,7 +38,7 @@ if(isset($_REQUEST['mode'])) {
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Action failed', 'title' => 'Action failed',
'redirect' => '/authenticate', 'redirect' => $urls->format('AUTH_ACTION'),
'message' => 'Invalid session, please try again.', 'message' => 'Invalid session, please try again.',
'success' => 0 'success' => 0
]; ];
@ -59,7 +59,7 @@ if(isset($_REQUEST['mode'])) {
// Add page specific things // Add page specific things
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Authentication', 'title' => 'Authentication',
'redirect' => '/', 'redirect' => $urls->format('SITE_HOME'),
'message' => 'You are already authenticated. Redirecting...', 'message' => 'You are already authenticated. Redirecting...',
'success' => 1 'success' => 1
]; ];
@ -79,7 +79,7 @@ if(isset($_REQUEST['mode'])) {
// Add page specific data // Add page specific data
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Logout', 'title' => 'Logout',
'redirect' => ($logout ? $_REQUEST['redirect'] : '/authenticate'), 'redirect' => ($logout ? $_REQUEST['redirect'] : $urls->format('SITE_LOGIN')),
'message' => $logout ? 'You are now logged out.' : 'An unknown error occurred.', 'message' => $logout ? 'You are now logged out.' : 'An unknown error occurred.',
'success' => $logout ? 1 : 0 'success' => $logout ? 1 : 0
]; ];
@ -105,7 +105,7 @@ if(isset($_REQUEST['mode'])) {
// Add page specific things // Add page specific things
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Forgot Password', 'title' => 'Forgot Password',
'redirect' => ($passforget[0] ? '/' : $_SERVER['PHP_SELF'] .'?pw=true&uid='. $_REQUEST['uid'] .'&verk='. $_REQUEST['verk']), 'redirect' => ($passforget[0] ? $urls->format('SITE_LOGIN') : $_SERVER['PHP_SELF'] .'?pw=true&uid='. $_REQUEST['uid'] .'&verk='. $_REQUEST['verk']),
'message' => $messages[$passforget[1]], 'message' => $messages[$passforget[1]],
'success' => $passforget[0] 'success' => $passforget[0]
]; ];
@ -130,7 +130,7 @@ if(isset($_REQUEST['mode'])) {
// Add page specific things // Add page specific things
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Activate account', 'title' => 'Activate account',
'redirect' => '/authenticate', 'redirect' => $urls->format('SITE_LOGIN'),
'message' => $messages[$activate[1]], 'message' => $messages[$activate[1]],
'success' => $activate[0] 'success' => $activate[0]
]; ];
@ -154,7 +154,7 @@ if(isset($_REQUEST['mode'])) {
// Add page specific things // Add page specific things
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Resend Activation', 'title' => 'Resend Activation',
'redirect' => '/authenticate', 'redirect' => $urls->format('SITE_HOME'),
'message' => $messages[$resend[1]], 'message' => $messages[$resend[1]],
'success' => $resend[0] 'success' => $resend[0]
]; ];
@ -180,7 +180,7 @@ if(isset($_REQUEST['mode'])) {
// Add page specific things // Add page specific things
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Login', 'title' => 'Login',
'redirect' => $login[0] ? $_REQUEST['redirect'] : '/authenticate', 'redirect' => $login[0] ? $_REQUEST['redirect'] : $urls->format('SITE_LOGIN'),
'message' => $messages[$login[1]], 'message' => $messages[$login[1]],
'success' => $login[0] 'success' => $login[0]
]; ];
@ -230,7 +230,7 @@ if(isset($_REQUEST['mode'])) {
// Add page specific things // Add page specific things
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Register', 'title' => 'Register',
'redirect' => ($register[0] ? '/' : '/authenticate'), 'redirect' => ($register[0] ? $urls->format('SITE_LOGIN') : $urls->format('SITE_REGISTER')),
'message' => $messages[$register[1]], 'message' => $messages[$register[1]],
'success' => $register[0] 'success' => $register[0]
]; ];
@ -254,7 +254,7 @@ if(isset($_REQUEST['mode'])) {
// Add page specific things // Add page specific things
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Lost Password', 'title' => 'Lost Password',
'redirect' => '/authenticate', 'redirect' => $urls->format('SITE_FORGOT_PASSWORD'),
'message' => $messages[$passforgot[1]], 'message' => $messages[$passforgot[1]],
'success' => $passforgot[0] 'success' => $passforgot[0]
]; ];
@ -276,7 +276,7 @@ if(isset($_REQUEST['mode'])) {
. '|' . '|'
. $renderData['page']['redirect'] . $renderData['page']['redirect']
) : ) :
Templates::render('errors/information.tpl', $renderData); Templates::render('global/information.tpl', $renderData);
exit; exit;
} }
@ -287,11 +287,11 @@ $renderData['page'] = [
]; ];
$renderData['auth'] = [ $renderData['auth'] = [
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/', 'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('SITE_HOME'),
'blockRegister' => [ 'blockRegister' => [
'do' => false 'do' => false
] ]
]; ];
@ -302,11 +302,11 @@ if(Users::checkLogin()) {
// Add page specific things // Add page specific things
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Authentication', 'title' => 'Authentication',
'redirect' => '/', '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.'
]; ];
print Templates::render('errors/information.tpl', $renderData); print Templates::render('global/information.tpl', $renderData);
exit; exit;
} }

View file

@ -343,9 +343,10 @@ a#gotop.exit {
.standalone { .standalone {
background: #C2AEEE; background: #C2AEEE;
padding: 10px; }
width: auto;
max-width: 1024px; .standalone > div {
padding: 5px 10px;
} }
.private-message { .private-message {
@ -671,13 +672,14 @@ a#gotop.exit {
.headerNotify { .headerNotify {
margin: 10px auto; margin: 10px auto;
padding: 2px 3px; padding: 10px 3px;
width: auto; width: auto;
max-width: 1024px; max-width: 1024px;
border: 1px solid #9475B2; border: 1px solid #9475B2;
box-shadow: 0 0 3px #9475B2; box-shadow: 0 0 3px #9475B2;
border-radius: 3px; border-radius: 3px;
background: #D3BFFF; background: #D3BFFF;
background: repeating-linear-gradient(-45deg, #C2AFFE, #C2AFFE 10px, #D3BFFF 10px, #D3BFFF 20px);
display: block; display: block;
text-align: center; text-align: center;
} }

View file

@ -0,0 +1,2 @@
# shhh
ErrorDocument 404 /content/images/flags/xx.png

View file

@ -8,48 +8,7 @@ namespace Sakura;
// Include components // Include components
require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) .'_sakura/sakura.php'; require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) .'_sakura/sakura.php';
/*
// Get group data
if(isset($_GET['g'])) {
$renderData['profile'] = [
'notset' => false,
'user' => ($_PROFILE_USER_DATA = Users::getUser(($_USER_USERNAME_ID = Users::userExists($_GET['u'], false)) ? $_USER_USERNAME_ID : $_GET['u'])),
'rank' => ($_PROFILE_RANK_DATA = Users::getRank($_PROFILE_USER_DATA['rank_main'])),
'colour' => ($_PROFILE_USER_DATA['name_colour'] == null ? $_PROFILE_RANK_DATA['colour'] : $_PROFILE_USER_DATA['name_colour']),
'ranktitle' => ($_PROFILE_USER_DATA['usertitle'] == null ? $_PROFILE_RANK_DATA['title'] : $_PROFILE_USER_DATA['usertitle']),
'data' => ($_PROFILE_PROFILE_DATA = Users::getUserProfileData($_PROFILE_USER_DATA, true)),
'country' => Main::getCountryName($_PROFILE_USER_DATA['country']),
'istenshi' => Users::checkUserTenshi($_PROFILE_USER_DATA['id']),
'online' => Users::checkUserOnline($_PROFILE_USER_DATA['id']),
'profilePage' => Users::getProfilePage($_PROFILE_PROFILE_DATA, true),
'fields' => Users::getUserProfileFields($_PROFILE_PROFILE_DATA, true),
'warnings' => Users::getWarnings($_PROFILE_USER_DATA['id']),
'friend' => Users::checkFriend($_PROFILE_USER_DATA['id'])
];
$renderData['page'] = [
'title' => ($_PROFILE_USER_DATA['id'] < 1 || $_PROFILE_USER_DATA['password_algo'] == 'nologin' ? 'User not found!' : 'Profile of '. $_PROFILE_USER_DATA['username']),
'style' => (!empty($_PROFILE_PROFILE_DATA['profileBackground']) ? [
'#userBackground' => [
'background' => 'url("/bg/'. $_PROFILE_USER_DATA['id'] .'") no-repeat center center / cover transparent !important',
'position' => 'fixed',
'top' => '0',
'bottom' => '0',
'right' => '0',
'left' => '0',
'z-index' => '-1'
]
] : null)
];
} else {
$renderData['profile']['notset'] = true;
$renderData['page']['title'] = 'User not found!';
}
// Print page contents // Print page contents
print Templates::render('main/profile.tpl', $renderData); print Templates::render('group/index.tpl', $renderData);
*/

View file

@ -62,9 +62,9 @@ $renderData['stats'] = [
'userCount' => ($_INDEX_USER_COUNT = count($_INDEX_USERS = Users::getAllUsers(false))), 'userCount' => ($_INDEX_USER_COUNT = count($_INDEX_USERS = Users::getAllUsers(false))),
'newestUser' => ($_INDEX_NEWEST_USER = new User(Users::getNewestUserId())), 'newestUser' => ($_INDEX_NEWEST_USER = new User(Users::getNewestUserId())),
'lastRegDate' => ($_INDEX_LAST_REGDATE = date_diff(date_create(date('Y-m-d', $_INDEX_NEWEST_USER->data['regdate'])), date_create(date('Y-m-d')))->format('%a')) .' day'. ($_INDEX_LAST_REGDATE == 1 ? '' : 's'), 'lastRegDate' => ($_INDEX_LAST_REGDATE = date_diff(date_create(date('Y-m-d', $_INDEX_NEWEST_USER->data['regdate'])), date_create(date('Y-m-d')))->format('%a')) .' day'. ($_INDEX_LAST_REGDATE == 1 ? '' : 's'),
'onlineUsers' => Users::checkAllOnline(), 'topicCount' => ($_TOPICS = count(Database::fetch('topics'))),
'topicCount' => ($_TOPICS = count(Database::fetch('topics'))), 'postCount' => ($_POSTS = count(Database::fetch('posts'))),
'postCount' => ($_POSTS = count(Database::fetch('posts'))) 'onlineUsers' => Users::checkAllOnline()
]; ];
// Print page contents // Print page contents

View file

@ -19,7 +19,7 @@ $renderData['page'] = [
'sort' => isset($_GET['sort']) && $_GET['sort'] && in_array($_GET['sort'], $_MEMBERLIST_SORTS) ? $_GET['sort'] : $_MEMBERLIST_SORTS[0], 'sort' => isset($_GET['sort']) && $_GET['sort'] && in_array($_GET['sort'], $_MEMBERLIST_SORTS) ? $_GET['sort'] : $_MEMBERLIST_SORTS[0],
'title' => isset($_GET['rank']) && $_GET['rank'] && !$_MEMBERLIST_NFOUND ? 'Viewing '. $_MEMBERLIST_RANKS[$_GET['rank']]['name'] . ($_MEMBERLIST_RANKS[$_GET['rank']]['multi'] ? 's' : '') : 'Member List', 'title' => isset($_GET['rank']) && $_GET['rank'] && !$_MEMBERLIST_NFOUND ? 'Viewing '. $_MEMBERLIST_RANKS[$_GET['rank']]['name'] . ($_MEMBERLIST_RANKS[$_GET['rank']]['multi'] ? 's' : '') : 'Member List',
'page' => isset($_GET['page']) && ($_GET['page'] - 1) >= 0 ? $_GET['page'] - 1 : 0, 'page' => isset($_GET['page']) && ($_GET['page'] - 1) >= 0 ? $_GET['page'] - 1 : 0,
'users' => array_chunk($_MEMBERLIST_ACTIVE && !$_MEMBERLIST_NFOUND ? Users::getUsersInRank($_MEMBERLIST_ACTIVE, null, true, true) : Users::getAllUsers(), 30, true) 'users' => array_chunk($_MEMBERLIST_ACTIVE && !$_MEMBERLIST_NFOUND ? Users::getUsersInRank($_MEMBERLIST_ACTIVE, null, true, true) : Users::getAllUsers(), Configuration::getConfig('members_per_page'), true)
]; ];

View file

@ -9,4 +9,4 @@ namespace Sakura;
// Include components // Include components
require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) .'_sakura/sakura.php'; require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) .'_sakura/sakura.php';
print 'not yet'; print Templates::render('main/report.tpl', $renderData);

View file

@ -62,14 +62,14 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$continue = true; $continue = true;
// Referrer // Referrer
$redirect = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/'); $redirect = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('SITE_INDEX'));
// Compare time and session so we know the link isn't forged // Compare time and session so we know the link isn't forged
if(!isset($_REQUEST['add']) && !isset($_REQUEST['remove'])) { if(!isset($_REQUEST['add']) && !isset($_REQUEST['remove'])) {
if(!isset($_REQUEST['ajax'])) { if(!isset($_REQUEST['ajax'])) {
header('Location: /settings/friends'); header('Location: '. $redirect);
exit; exit;
} }
@ -207,13 +207,16 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
. '|' . '|'
. $renderData['page']['redirect'] . $renderData['page']['redirect']
) : ) :
Templates::render('errors/information.tpl', $renderData); Templates::render('global/information.tpl', $renderData);
exit; exit;
} elseif(isset($_POST['submit']) && isset($_POST['submit'])) { } elseif(isset($_POST['submit']) && isset($_POST['submit'])) {
$continue = true; $continue = true;
// Set redirector
$redirect = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('SETTINGS_INDEX');
// Check if the user is logged in // Check if the user is logged in
if(!Users::checkLogin() || !$continue) { if(!Users::checkLogin() || !$continue) {
@ -236,7 +239,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Session expired', 'title' => 'Session expired',
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'Your session has expired, please refresh the page and try again.', 'message' => 'Your session has expired, please refresh the page and try again.',
'success' => 0 'success' => 0
@ -283,7 +286,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => $msgTitle, 'title' => $msgTitle,
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'You are not allowed to alter your '. strtolower($msgTitle) .'.', 'message' => 'You are not allowed to alter your '. strtolower($msgTitle) .'.',
'success' => 0 'success' => 0
@ -305,7 +308,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => $msgTitle, 'title' => $msgTitle,
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'No file was uploaded.', 'message' => 'No file was uploaded.',
'success' => 0 'success' => 0
@ -346,7 +349,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => $msgTitle, 'title' => $msgTitle,
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => $msg, 'message' => $msg,
'success' => 0 'success' => 0
@ -369,7 +372,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => $msgTitle, 'title' => $msgTitle,
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'Uploaded file is not an image.', 'message' => 'Uploaded file is not an image.',
'success' => 0 'success' => 0
@ -386,7 +389,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => $msgTitle, 'title' => $msgTitle,
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'This filetype is not allowed.', 'message' => 'This filetype is not allowed.',
'success' => 0 'success' => 0
@ -403,7 +406,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => $msgTitle, 'title' => $msgTitle,
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'The resolution of this picture is too big.', 'message' => 'The resolution of this picture is too big.',
'success' => 0 'success' => 0
@ -420,7 +423,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => $msgTitle, 'title' => $msgTitle,
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'The resolution of this picture is too small.', 'message' => 'The resolution of this picture is too small.',
'success' => 0 'success' => 0
@ -437,7 +440,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => $msgTitle, 'title' => $msgTitle,
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'The filesize of this file is too large.', 'message' => 'The filesize of this file is too large.',
'success' => 0 'success' => 0
@ -467,7 +470,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => $msgTitle, 'title' => $msgTitle,
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'Something went wrong, please try again.', 'message' => 'Something went wrong, please try again.',
'success' => 0 'success' => 0
@ -492,7 +495,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => $msgTitle, 'title' => $msgTitle,
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'Updated your '. strtolower($msgTitle) .'!', 'message' => 'Updated your '. strtolower($msgTitle) .'!',
'success' => 1 'success' => 1
@ -549,7 +552,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Profile update', 'title' => 'Profile update',
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'Your profile has been updated!', 'message' => 'Your profile has been updated!',
'success' => 1 'success' => 1
@ -586,7 +589,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Options change', 'title' => 'Options change',
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'Changed your options!', 'message' => 'Changed your options!',
'success' => 1 'success' => 1
@ -595,7 +598,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
break; break;
// Userpage // Userpage
case 'userpage': /*case 'userpage':
// Base64 encode the userpage // Base64 encode the userpage
$userPage = base64_encode($_POST['userpage']); $userPage = base64_encode($_POST['userpage']);
@ -607,13 +610,13 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Userpage', 'title' => 'Userpage',
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'Your userpage has been updated!', 'message' => 'Your userpage has been updated!',
'success' => 1 'success' => 1
]; ];
break; break;*/
// Fallback // Fallback
default: default:
@ -622,7 +625,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
$renderData['page'] = [ $renderData['page'] = [
'title' => 'Unknown action', 'title' => 'Unknown action',
'redirect' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/settings', 'redirect' => $redirect,
'message' => 'The requested method does not exist.', 'message' => 'The requested method does not exist.',
'success' => 0 'success' => 0
@ -645,7 +648,7 @@ if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications
. '|' . '|'
. $renderData['page']['redirect'] . $renderData['page']['redirect']
) : ) :
Templates::render('errors/information.tpl', $renderData); Templates::render('global/information.tpl', $renderData);
exit; exit;
} }
@ -981,7 +984,7 @@ if(Users::checkLogin()) {
if(!$category || empty($category) || !$mode || empty($mode) || !$pages[$category]['modes'][$mode]['access']) { if(!$category || empty($category) || !$mode || empty($mode) || !$pages[$category]['modes'][$mode]['access']) {
header('HTTP/1.0 404 Not Found'); header('HTTP/1.0 404 Not Found');
print Templates::render('errors/http404.tpl', $renderData); print Templates::render('global/notfound.tpl', $renderData);
exit; exit;
} }

View file

@ -15,7 +15,7 @@ if(isset($_REQUEST['mode']) && Users::checkLogin() && Permissions::check('SITE',
// Initialise Payments class // Initialise Payments class
if(!Payments::init()) { if(!Payments::init()) {
header('Location: /support?fail=true'); header('Location: '. $urls->format('SITE_PREMIUM') .'?fail=true');
} else { } else {
@ -27,7 +27,7 @@ if(isset($_REQUEST['mode']) && Users::checkLogin() && Permissions::check('SITE',
// Compare time and session so we know the link isn't forged // Compare time and session so we know the link isn't forged
if(!isset($_REQUEST['time']) || $_REQUEST['time'] < time() - 1000) { if(!isset($_REQUEST['time']) || $_REQUEST['time'] < time() - 1000) {
header('Location: /support?fail=true'); header('Location: '. $urls->format('SITE_PREMIUM') .'?fail=true');
break; break;
} }
@ -35,7 +35,7 @@ if(isset($_REQUEST['mode']) && Users::checkLogin() && Permissions::check('SITE',
// Match session ids for the same reason // Match session ids for the same reason
if(!isset($_REQUEST['session']) || $_REQUEST['session'] != session_id()) { if(!isset($_REQUEST['session']) || $_REQUEST['session'] != session_id()) {
header('Location: /support?fail=true'); header('Location: '. $urls->format('SITE_PREMIUM') .'?fail=true');
break; break;
} }
@ -43,7 +43,7 @@ if(isset($_REQUEST['mode']) && Users::checkLogin() && Permissions::check('SITE',
// Half if shit isn't gucci // Half if shit isn't gucci
if(!isset($_POST['months']) || !is_numeric($_POST['months']) || (int)$_POST['months'] < 1 || (int)$_POST['months'] > Configuration::getConfig('premium_amount_max')) { if(!isset($_POST['months']) || !is_numeric($_POST['months']) || (int)$_POST['months'] < 1 || (int)$_POST['months'] > Configuration::getConfig('premium_amount_max')) {
header('Location: /support?fail=true'); header('Location: '. $urls->format('SITE_PREMIUM') .'?fail=true');
} else { } else {
@ -55,7 +55,7 @@ if(isset($_REQUEST['mode']) && Users::checkLogin() && Permissions::check('SITE',
$itemName = Configuration::getConfig('sitename') .' Premium - '. (string)$_POST['months'] .' month'. ((int)$_POST['months'] == 1 ? '' : 's'); $itemName = Configuration::getConfig('sitename') .' Premium - '. (string)$_POST['months'] .' month'. ((int)$_POST['months'] == 1 ? '' : 's');
// Attempt to create a transaction // Attempt to create a transaction
if($transaction = Payments::createTransaction($total, $itemName, Configuration::getConfig('sitename') .' Premium Purchase', 'http://'. Configuration::getConfig('url_main') .'/support')) { if($transaction = Payments::createTransaction($total, $itemName, Configuration::getConfig('sitename') .' Premium Purchase', 'http://'. Configuration::getConfig('url_main') . $urls->format('SITE_PREMIUM'))) {
// Store the amount of months in the global session array // Store the amount of months in the global session array
$_SESSION['premiumMonths'] = (int)$_POST['months']; $_SESSION['premiumMonths'] = (int)$_POST['months'];
@ -65,7 +65,7 @@ if(isset($_REQUEST['mode']) && Users::checkLogin() && Permissions::check('SITE',
} else { } else {
header('Location: /support?fail=true'); header('Location: '. $urls->format('SITE_PREMIUM') .'?fail=true');
} }
@ -93,18 +93,18 @@ if(isset($_REQUEST['mode']) && Users::checkLogin() && Permissions::check('SITE',
Main::updatePremiumTracker(Session::$userId, ((float)Configuration::getConfig('premium_price_per_month') * $_SESSION['premiumMonths']), $currentUser->data['username'] .' bought premium for '. $_SESSION['premiumMonths'] .' month'. ($_SESSION['premiumMonths'] == 1 ? '' : 's') .'.'); Main::updatePremiumTracker(Session::$userId, ((float)Configuration::getConfig('premium_price_per_month') * $_SESSION['premiumMonths']), $currentUser->data['username'] .' bought premium for '. $_SESSION['premiumMonths'] .' month'. ($_SESSION['premiumMonths'] == 1 ? '' : 's') .'.');
// Redirect to the complete // Redirect to the complete
header('Location: ?mode=complete'); header('Location: '. $urls->format('SITE_PREMIUM') .'?mode=complete');
exit; exit;
} }
} }
header('Location: /support?fail=true'); header('Location: '. $urls->format('SITE_PREMIUM') .'?fail=true');
break; break;
case 'complete': case 'complete':
print Templates::render('errors/premiumComplete.tpl', array_merge([ print Templates::render('main/premiumcomplete.tpl', array_merge([
'page' => [ 'page' => [
'title' => 'Premium purchase complete!', 'title' => 'Premium purchase complete!',
'expiration' => ($prem = Users::checkUserPremium(Session::$userId)[2]) !== null ? $prem : 0 'expiration' => ($prem = Users::checkUserPremium(Session::$userId)[2]) !== null ? $prem : 0
@ -113,7 +113,7 @@ if(isset($_REQUEST['mode']) && Users::checkLogin() && Permissions::check('SITE',
break; break;
default: default:
header('Location: /support'); header('Location: '. $urls->format('SITE_PREMIUM'));
break; break;
} }

View file

@ -24,7 +24,7 @@ if(!$forum) {
]; ];
// Print template // Print template
print Templates::render('errors/information.tpl', $renderData); print Templates::render('global/information.tpl', $renderData);
exit; exit;
} }
@ -42,7 +42,7 @@ if($forum['forum']['forum_type'] === 2) {
]; ];
// Print template // Print template
print Templates::render('errors/information.tpl', $renderData); print Templates::render('global/information.tpl', $renderData);
exit; exit;
} }

View file

@ -24,7 +24,7 @@ if(!$topic) {
]; ];
// Print template // Print template
print Templates::render('errors/information.tpl', $renderData); print Templates::render('global/information.tpl', $renderData);
exit; exit;
} }