diff --git a/banned.php b/banned.php deleted file mode 100644 index 57e4a9bc..00000000 --- a/banned.php +++ /dev/null @@ -1,7 +0,0 @@ -"._("Banned?").""; - print "

"._("You are not banned.")."

"; - print ""; -?> diff --git a/banners.php b/banners.php index 2707ca5c..fd345cc9 100644 --- a/banners.php +++ b/banners.php @@ -8,7 +8,7 @@ header("Expires: 0"); function get_custom_banner(&$b) { # Validate the board name - if (!(isset($b) && preg_match('/^[a-z0-9]{1,30}$/', $b))) + if (!(isset($b) && preg_match('/^[a-z0-9+]{1,30}$/', $b))) return null; # Check if directory exists diff --git a/faq.php b/faq.php index 2ea68f72..4644d501 100644 --- a/faq.php +++ b/faq.php @@ -65,9 +65,9 @@ $body = <<

How are featured boards chosen?

-

Top fifteen boards excluding /meta/, /b/ and /int/.

+

Top fifteen boards excluding /meta/, /b/ and /pol/.

-

Who owns /meta/, /b/, and /int/?

+

Who owns /meta/ and /b/?

No one, so they are de facto property of the administration.

Where's the mobile app?

@@ -76,12 +76,22 @@ $body = <<I don't provide support for this app, ask the developer of it if you have a problem with it.

Where's the archive?

-

There isn't one yet and there will never be an official archive.

+

There isn't one yet and there will never be an official archive.

+

Given that archives are inevitable and will be created anyway via archive.today, Google cache, and anyone who installs Asagi, I'm softening my stance on this. Currently, 8archive.moe provides our archive, and I may set up an official one. All archives officially partnered with us will be opt-in by our board owners, not opt-out. Archives who archive boards that have not opted in will be considered pirate archives, and legal action may be taken.

+ +

I got an email from an @8chan.co email address, is that you?

+

8chan.co uses cock.li to manage our domain's email. cock.li allows anyone to create an email account @8chan.co.

+

That said, we have quite a few official 8chan.co email addresses. They are:

+

How do I donate?

Donations can be sent to 1NpQaXqmCBji6gfX8UgaQEmEstvVY7U32C (Bitcoin) or LUPgSCJt3iGeJXUETVhmnbQ89Riaq1yjZm (Litecoin).

+

I am also a big fan of Monero (XMR). You can send XMR to our OpenAlias in the simplewallet client, or simply send to 49dBJhGhYFxJEfydS6hH6GRyg1W4cDgupdNVtw7j1WtcUY7xPXwNLw6fUVay644viaCcEhMFG1Z7SjjxRXEFDdNWJdvH9kS.

You may also donate monthly via Patreon at http://www.patreon.com/user?u=162165. -

Are you really a cripple?

Yes.

diff --git a/inc/8chan-mod-pages.php b/inc/8chan-mod-pages.php index 4c8e3b90..33a6e752 100644 --- a/inc/8chan-mod-pages.php +++ b/inc/8chan-mod-pages.php @@ -22,6 +22,7 @@ $config['mod']['clean_global'] = GLOBALVOLUNTEER; $config['mod']['view_notes'] = DISABLED; $config['mod']['create_notes'] = DISABLED; + $config['mod']['edit_config'] = DISABLED; $config['mod']['debug_recent'] = ADMIN; $config['mod']['debug_antispam'] = ADMIN; $config['mod']['noticeboard_post'] = ADMIN; @@ -155,14 +156,16 @@ error(sprintf($config['error']['required'], 'username')); if ($_POST['password'] == '') error(sprintf($config['error']['required'], 'password')); + if (!preg_match('/^[a-zA-Z0-9._]{1,30}$/', $_POST['username'])) + error(_('Invalid username')); if ($count > 10) { error(_('Too many board volunteers!')); } foreach ($volunteers as $i => $v) { - if ($_POST['username'] == $v['username']) { - error(_('Refusing to create a volunteer with the same username as an existing one.')); + if (strtolower($_POST['username']) == strtolower($v['username'])) { + error(_('Refusing to create a volunteer with the same username as an existing one.')); } } diff --git a/inc/config.php b/inc/config.php index b54d0e0f..1769ed6a 100644 --- a/inc/config.php +++ b/inc/config.php @@ -1083,6 +1083,7 @@ $config['error']['youaremuted'] = _('You are muted! Expires in %d seconds.'); $config['error']['dnsbl'] = _('Your IP address is listed in %s.'); $config['error']['toomanylinks'] = _('Too many links; flood detected.'); + $config['error']['notenoughlinks'] = _('OPs are required to have at least %d links on this board.'); $config['error']['toomanycites'] = _('Too many cites; post discarded.'); $config['error']['toomanycross'] = _('Too many cross-board links; post discarded.'); $config['error']['nodelete'] = _('You didn\'t select anything to delete.'); @@ -1680,7 +1681,7 @@ // Regex for board URIs. Don't add "`" character or any Unicode that MySQL can't handle. 58 characters // is the absolute maximum, because MySQL cannot handle table names greater than 64 characters. - $config['board_regex'] = '[0-9a-zA-Z$_\x{0080}-\x{FFFF}]{1,58}'; + $config['board_regex'] = '[0-9a-zA-Z\+$_\x{0080}-\x{FFFF}]{1,58}'; // Youtube.js embed HTML code $config['youtube_js_html'] = '
'. diff --git a/inc/functions.php b/inc/functions.php index 2d505173..dd02ce79 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -432,7 +432,8 @@ function setupBoard($array) { $board = array( 'uri' => $array['uri'], 'title' => $array['title'], - 'subtitle' => $array['subtitle'] + 'subtitle' => $array['subtitle'], + 'indexed' => $array['indexed'] ); // older versions @@ -1703,7 +1704,7 @@ function extract_modifiers($body) { return $modifiers; } -function markup(&$body, $track_cites = false) { +function markup(&$body, $track_cites = false, $op = false) { global $board, $config, $markup_urls; $modifiers = extract_modifiers($body); @@ -1741,6 +1742,9 @@ function markup(&$body, $track_cites = false) { if ($num_links > $config['max_links']) error($config['error']['toomanylinks']); + + if ($num_links < $config['min_links'] && $op) + error(sprintf($config['error']['notenoughlinks'], $config['min_links'])); } if ($config['markup_repair_tidy']) diff --git a/inc/instance-config.php b/inc/instance-config.php index 2c183707..896eb3a1 100644 --- a/inc/instance-config.php +++ b/inc/instance-config.php @@ -74,7 +74,7 @@ $config['mod']['capcode'][MOD] = array('Board Owner'); $config['mod']['capcode'][GLOBALVOLUNTEER] = array('Global Volunteer'); $config['custom_capcode']['Admin'] = array( - ' %s', + ' 8chan.co Administrator', ); //$config['mod']['view_banlist'] = GLOBALVOLUNTEER; $config['mod']['recent_reports'] = 65535; @@ -91,6 +91,7 @@ //$config['default_stylesheet'] = array('Notsuba', 'notsuba.css'); $config['additional_javascript'][] = 'js/jquery.min.js'; $config['additional_javascript'][] = 'js/jquery.mixitup.min.js'; + $config['additional_javascript'][] = 'js/jquery-ui.custom.min.js'; $config['additional_javascript'][] = 'js/catalog.js'; $config['additional_javascript'][] = 'js/captcha.js'; $config['additional_javascript'][] = 'js/jquery.tablesorter.min.js'; @@ -150,8 +151,9 @@ $config['markup'][] = array("/\[spoiler\](.+?)\[\/spoiler\]/", "\$1"); $config['markup'][] = array("/~~(.+?)~~/", "\$1"); $config['markup'][] = array("/__(.+?)__/", "\$1"); + $config['markup'][] = array("/###([^\s']+)###/", "###\$1###"); - $config['boards'] = array(array('' => '/', '' => '/boards.html', '' => '/faq.html', '' => '/random.php', '' => '/create.php', '' => '/bans.html', '' => '/search.php', '' => '/mod.php', '' => 'https://qchat.rizon.net/?channels=#8chan'), array('b', 'meta'), array(''=>'https://twitter.com/infinitechan')); + $config['boards'] = array(array('' => '/', '' => '/boards.html', '' => '/faq.html', '' => '/random.php', '' => '/create.php', '' => '/bans.html', '' => '/search.php', '' => '/mod.php', '' => 'https://qchat.rizon.net/?channels=#8chan'), array('b', 'meta', 'news+'), array(''=>'https://twitter.com/infinitechan')); //$config['boards'] = array(array('' => '/', '' => '/boards.html', '' => '/faq.html', '' => '/random.php', '' => '/create.php', '' => '/search.php', '' => '/mod.php', '' => 'https://qchat.rizon.net/?channels=#8chan'), array('b', 'meta', 'int'), array('v', 'a', 'tg', 'fit', 'pol', 'tech', 'mu', 'co', 'sp', 'boards'), array(''=>'https://twitter.com/infinitechan')); $config['footer'][] = 'All posts on 8chan.co are the responsibility of the individual poster and not the administration of 8chan.co, pursuant to 47 U.S.C. § 230.'; @@ -195,6 +197,9 @@ $config['gzip_static'] = false; $config['hash_masked_ip'] = true; +$config['force_subject_op'] = false; +$config['min_links'] = 0; +$config['min_body'] = 0; // 8chan specific mod pages require '8chan-mod-pages.php'; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 0f059f05..a933f95a 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -633,7 +633,7 @@ function mod_news($page_no = 1) { rebuildThemes('news'); - header('Location: ?/news#' . $pdo->lastInsertId(), true, $config['redirect_http']); + header('Location: ?/edit_news#' . $pdo->lastInsertId(), true, $config['redirect_http']); } $query = prepare("SELECT * FROM ``news`` ORDER BY `id` DESC LIMIT :offset, :limit"); @@ -646,14 +646,14 @@ function mod_news($page_no = 1) { error($config['error']['404']); foreach ($news as &$entry) { - $entry['delete_token'] = make_secure_link_token('news/delete/' . $entry['id']); + $entry['delete_token'] = make_secure_link_token('edit_news/delete/' . $entry['id']); } $query = prepare("SELECT COUNT(*) FROM ``news``"); $query->execute() or error(db_error($query)); $count = $query->fetchColumn(); - mod_page(_('News'), 'mod/news.html', array('news' => $news, 'count' => $count, 'token' => make_secure_link_token('news'))); + mod_page(_('News'), 'mod/news.html', array('news' => $news, 'count' => $count, 'token' => make_secure_link_token('edit_news'))); } function mod_news_delete($id) { @@ -668,7 +668,7 @@ function mod_news_delete($id) { modLog('Deleted a news entry'); - header('Location: ?/news', true, $config['redirect_http']); + header('Location: ?/edit_news', true, $config['redirect_http']); } function mod_log($page_no = 1) { diff --git a/js/update_boards.js b/js/update_boards.js index 127d0874..439ddb14 100644 --- a/js/update_boards.js +++ b/js/update_boards.js @@ -4,7 +4,7 @@ window.boards = new Array(); function handle_boards(data) { $.each(data, function(k, v) { if (v.uri != 'meta' && v.uri != 'b') { - boards.push(''+v.uri+''); + boards.push(''+v.uri+''); } }) diff --git a/mod.php b/mod.php index 45c836ac..18dffec3 100644 --- a/mod.php +++ b/mod.php @@ -42,9 +42,9 @@ $pages = array( '/log/(\d+)' => 'log', // modlog '/log:([^/]+)' => 'user_log', // modlog '/log:([^/]+)/(\d+)' => 'user_log', // modlog - '/news' => 'secure_POST news', // view news - '/news/(\d+)' => 'secure_POST news', // view news - '/news/delete/(\d+)' => 'secure news_delete', // delete from news + '/edit_news' => 'secure_POST news', // view news + '/edit_news/(\d+)' => 'secure_POST news', // view news + '/edit_news/delete/(\d+)' => 'secure news_delete', // delete from news '/noticeboard' => 'secure_POST noticeboard', // view noticeboard '/noticeboard/(\d+)' => 'secure_POST noticeboard', // view noticeboard diff --git a/post.php b/post.php index 1a7c5da2..d28f50d6 100644 --- a/post.php +++ b/post.php @@ -394,11 +394,19 @@ elseif (isset($_POST['post'])) { $post['has_file'] = (!isset($post['embed']) && (($post['op'] && !isset($post['no_longer_require_an_image_for_op']) && $config['force_image_op']) || !empty($_FILES['file']['name']))); if (!($post['has_file'] || isset($post['embed'])) || (($post['op'] && $config['force_body_op']) || (!$post['op'] && $config['force_body']))) { - $stripped_whitespace = preg_replace('/[\s]/u', '', $post['body']); + // http://stackoverflow.com/a/4167053 + $stripped_whitespace = preg_replace('/^[\pZ\pC]+|[\pZ\pC]+$/u', '', $post['body']); if ($stripped_whitespace == '') { error($config['error']['tooshort_body']); } } + + if ($config['force_subject_op'] && $post['op']) { + $stripped_whitespace = preg_replace('/^[\pZ\pC]+|[\pZ\pC]+$/u', '', $post['subject']); + if ($stripped_whitespace == '') { + error(_('It is required to enter a subject when starting a new thread on this board.')); + } + } if (!$post['op']) { // Check if thread is locked @@ -523,6 +531,8 @@ elseif (isset($_POST['post'])) { error(sprintf($config['error']['toolong'], 'subject')); if (!$mod && mb_strlen($post['body']) > $config['max_body']) error($config['error']['toolong_body']); + if (mb_strlen($post['body']) < $config['min_body'] && $post['op']) + error(_(sprintf('OP must be at least %d chars on this board.', $config['min_body']))); if (mb_strlen($post['password']) > 20) error(sprintf($config['error']['toolong'], 'password')); @@ -588,7 +598,7 @@ elseif (isset($_POST['post'])) { } } - $post['tracked_cites'] = markup($post['body'], true); + $post['tracked_cites'] = markup($post['body'], true, $post['op']); diff --git a/templates/index.html b/templates/index.html index 5638fd65..e422b8bc 100644 --- a/templates/index.html +++ b/templates/index.html @@ -18,7 +18,7 @@ {{ boardlist.top }} {% if pm %}
You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

{% endif %} - {% if config.url_banner %}{% endif %} + {% if config.url_banner %}{% endif %}

{{ board.url }} - {{ board.title|e }}

diff --git a/templates/main.js b/templates/main.js index 0156e23b..23af9447 100644 --- a/templates/main.js +++ b/templates/main.js @@ -188,7 +188,7 @@ function changeStyle(styleName, link) { {% endraw %} function init_stylechooser() { - var matches = document.URL.match(/\/(\w+)\/($|{{ config.dir.res|replace({'/': '\\/'}) }}{{ config.file_page|replace({'%d': '\\d+', '.': '\\.'}) }}|{{ config.file_index|replace({'.': '\\.'}) }}|{{ config.dir.res|replace({'/': '\\/'}) }}{{ config.file_page50|replace({'+': '\\+', '%d': '\\d+', '.': '\\.'}) }}|{{ config.file_page|replace({'%d': '\\d+', '.': '\\.'}) }}|{{ config.catalog_link|replace({'.': '\\.'}) }})/); + var matches = document.URL.match(/\/([0-9a-zA-Z\+$_\u0080-\uFFFF]{1,58})\/($|{{ config.dir.res|replace({'/': '\\/'}) }}{{ config.file_page|replace({'%d': '\\d+', '.': '\\.'}) }}|{{ config.file_index|replace({'.': '\\.'}) }}|{{ config.dir.res|replace({'/': '\\/'}) }}{{ config.file_page50|replace({'+': '\\+', '%d': '\\d+', '.': '\\.'}) }}|{{ config.file_page|replace({'%d': '\\d+', '.': '\\.'}) }}|{{ config.catalog_link|replace({'.': '\\.'}) }})/); var newElement = document.createElement('div'); newElement.className = 'styles'; @@ -255,9 +255,10 @@ function get_cookie(cookie_name) { } function highlightReply(id) { - if (typeof window.event != "undefined" && event.which == 2) { + if (typeof window.event != "undefined") { // don't highlight on middle click - return true; + if (event.which == 2) return true; + window.event.preventDefault(); } var divs = document.getElementsByTagName('div'); @@ -268,9 +269,18 @@ function highlightReply(id) { } if (id) { var post = document.getElementById('reply_'+id); - if (post) + if (post) { post.className += ' highlighted'; window.location.hash = id; + + // Better offset to keep in mind new hovering boardlist + var post_top = post.getBoundingClientRect().top; + var body_top = document.body.getBoundingClientRect().top; + var boardlist_height = document.getElementsByClassName('boardlist')[0].getBoundingClientRect().height; + var offset = (post_top - body_top) - boardlist_height; + + window.scrollTo(0, offset); + } } return true; } diff --git a/templates/thread.html b/templates/thread.html index 0a78f274..61b6e152 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -13,7 +13,7 @@ {{ boardlist.top }} {% if pm %}
You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

{% endif %} - {% if config.url_banner %}{% endif %} + {% if config.url_banner %}{% endif %}

{{ board.url }} - {{ board.title|e }}