mirror of
https://github.com/vichan-devel/vichan.git
synced 2024-11-27 17:00:52 +01:00
Improved Tinyboard anti-bot/spam filter. See large comment in inc/config.php for details.
This commit is contained in:
parent
dd0f421015
commit
a564a95ab4
@ -12,8 +12,7 @@ if(realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) {
|
|||||||
$hidden_inputs_twig = array();
|
$hidden_inputs_twig = array();
|
||||||
|
|
||||||
class AntiBot {
|
class AntiBot {
|
||||||
public $inputs = array(), $index = 0;
|
public $salt, $inputs = array(), $index = 0;
|
||||||
private $salt;
|
|
||||||
|
|
||||||
public static function randomString($length, $uppercase = false, $special_chars = false) {
|
public static function randomString($length, $uppercase = false, $special_chars = false) {
|
||||||
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
@ -90,12 +89,14 @@ class AntiBot {
|
|||||||
$this->inputs[$name] = (string)rand(0, 100);
|
$this->inputs[$name] = (string)rand(0, 100);
|
||||||
} else {
|
} else {
|
||||||
// Obscure value
|
// Obscure value
|
||||||
$this->inputs[$name] = $this->randomString(rand(5, 100));
|
$this->inputs[$name] = $this->randomString(rand(5, 100), true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function html($count = false) {
|
public function html($count = false) {
|
||||||
|
global $config;
|
||||||
|
|
||||||
$elements = array(
|
$elements = array(
|
||||||
'<input type="hidden" name="%name%" value="%value%">',
|
'<input type="hidden" name="%name%" value="%value%">',
|
||||||
'<input type="hidden" value="%value%" name="%name%">',
|
'<input type="hidden" value="%value%" name="%name%">',
|
||||||
@ -110,7 +111,11 @@ class AntiBot {
|
|||||||
|
|
||||||
$html = '';
|
$html = '';
|
||||||
|
|
||||||
if($count == 0) {
|
if($count === false) {
|
||||||
|
$count = rand(1, count($this->inputs) / 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($count === true) {
|
||||||
// all elements
|
// all elements
|
||||||
$inputs = array_slice($this->inputs, $this->index);
|
$inputs = array_slice($this->inputs, $this->index);
|
||||||
} else {
|
} else {
|
||||||
@ -134,7 +139,10 @@ class AntiBot {
|
|||||||
$value = $this->make_confusing($value);
|
$value = $this->make_confusing($value);
|
||||||
else
|
else
|
||||||
$value = utf8tohtml($value);
|
$value = utf8tohtml($value);
|
||||||
|
|
||||||
|
if(strpos($element, 'textarea') === false)
|
||||||
|
$value = str_replace('"', '"', $value);
|
||||||
|
|
||||||
$element = str_replace('%value%', $value, $element);
|
$element = str_replace('%value%', $value, $element);
|
||||||
|
|
||||||
$html .= $element;
|
$html .= $element;
|
||||||
@ -162,36 +170,42 @@ class AntiBot {
|
|||||||
// Use SHA1 for the hash
|
// Use SHA1 for the hash
|
||||||
return sha1($hash . $this->salt);
|
return sha1($hash . $this->salt);
|
||||||
}
|
}
|
||||||
};;
|
|
||||||
|
|
||||||
|
|
||||||
function hiddenInputs(array $salt, $print_the_rest = false) {
|
|
||||||
global $hidden_inputs_twig;
|
|
||||||
|
|
||||||
$salt_str = implode(':', $salt);
|
|
||||||
|
|
||||||
if(!isset($hidden_inputs_twig[$salt_str]))
|
|
||||||
$hidden_inputs_twig[$salt_str] = new AntiBot($salt);
|
|
||||||
|
|
||||||
if($print_the_rest)
|
|
||||||
return $hidden_inputs_twig[$salt_str]->html(0);
|
|
||||||
else
|
|
||||||
return $hidden_inputs_twig[$salt_str]->html(rand(1, 5));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function hiddenInputsHash(array $salt) {
|
function _create_antibot($board, $thread) {
|
||||||
global $hidden_inputs_twig;
|
global $config;
|
||||||
|
|
||||||
$salt_str = implode(':', $salt);
|
$antibot = new AntiBot(array($board, $thread));
|
||||||
|
|
||||||
if(!isset($hidden_inputs_twig[$salt_str]))
|
query('DELETE FROM `antispam` WHERE `expires` < UNIX_TIMESTAMP()') or error(db_error($query));
|
||||||
$hidden_inputs_twig[$salt_str] = new AntiBot($salt);
|
|
||||||
|
|
||||||
return $hidden_inputs_twig[$salt_str]->hash();
|
if($thread)
|
||||||
|
$query = prepare('UPDATE `antispam` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE `board` = :board AND `thread` = :thread');
|
||||||
|
else
|
||||||
|
$query = prepare('UPDATE `antispam` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE `board` = :board AND `thread` IS NULL');
|
||||||
|
|
||||||
|
$query->bindValue(':board', $board);
|
||||||
|
if($thread)
|
||||||
|
$query->bindValue(':thread', $thread);
|
||||||
|
$query->bindValue(':expires', $config['spam']['hidden_inputs_expire']);
|
||||||
|
$query->execute() or error(db_error($query));
|
||||||
|
|
||||||
|
$query = prepare('INSERT INTO `antispam` VALUES (:board, :thread, CRC32(:hash), UNIX_TIMESTAMP(), NULL, 0)');
|
||||||
|
$query->bindValue(':board', $board);
|
||||||
|
$query->bindValue(':thread', $thread);
|
||||||
|
$query->bindValue(':hash', $antibot->hash());
|
||||||
|
$query->execute() or error(db_error($query));
|
||||||
|
|
||||||
|
if($query->rowCount() == 0) {
|
||||||
|
// there was no database entry for this hash. most likely expired.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $antibot;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSpam(array $extra_salt = array()) {
|
function checkSpam(array $extra_salt = array()) {
|
||||||
global $config;
|
global $config, $pdo;
|
||||||
|
|
||||||
if(!isset($_POST['hash']))
|
if(!isset($_POST['hash']))
|
||||||
return true;
|
return true;
|
||||||
@ -231,6 +245,25 @@ function checkSpam(array $extra_salt = array()) {
|
|||||||
// Use SHA1 for the hash
|
// Use SHA1 for the hash
|
||||||
$_hash = sha1($_hash . $extra_salt);
|
$_hash = sha1($_hash . $extra_salt);
|
||||||
|
|
||||||
return $hash != $_hash;
|
if($hash != $_hash)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
$query = prepare('UPDATE `antispam` SET `passed` = `passed` + 1 WHERE `hash` = CRC32(:hash)');
|
||||||
|
$query->bindValue(':hash', $hash);
|
||||||
|
$query->execute() or error(db_error($query));
|
||||||
|
if($query->rowCount() == 0) {
|
||||||
|
// there was no database entry for this hash. most likely expired.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = prepare('SELECT `passed` FROM `antispam` WHERE `hash` = CRC32(:hash)');
|
||||||
|
$query->bindValue(':hash', $hash);
|
||||||
|
$query->execute() or error(db_error($query));
|
||||||
|
$passed = $query->fetchColumn(0);
|
||||||
|
|
||||||
|
if($passed > $config['spam']['hidden_inputs_max_pass'])
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,9 +170,33 @@
|
|||||||
// Skip checking certain IP addresses against blacklists (for troubleshooting or whatever)
|
// Skip checking certain IP addresses against blacklists (for troubleshooting or whatever)
|
||||||
$config['dnsbl_exceptions'][] = '127.0.0.1';
|
$config['dnsbl_exceptions'][] = '127.0.0.1';
|
||||||
|
|
||||||
// Spam filter
|
/*
|
||||||
|
* Introduction to Tinyboard's spam filter:
|
||||||
|
*
|
||||||
|
* In simple terms, whenever a posting form on a page is generated (which happens whenever a
|
||||||
|
* post is made), Tinyboard will add a random amount of hidden, obscure fields to it to
|
||||||
|
* confuse bots and upset hackers. These fields and their respective obscure values are
|
||||||
|
* validated upon posting with a 160-bit "hash". That hash can only be used as many times
|
||||||
|
* as you specify; otherwise, flooding bots could just keep reusing the same hash.
|
||||||
|
* Once a new set of inputs (and the hash) are generated, old hashes for the same thread
|
||||||
|
* and board are set to expire. Because you have to reload the page to get the new set
|
||||||
|
* of inputs and hash, if they expire too quickly and more than one person is viewing the
|
||||||
|
* page at a given time, Tinyboard would return false positives (depending on how long the
|
||||||
|
* user sits on the page before posting). If your imageboard is quite fast/popular, set
|
||||||
|
* $config['spam']['hidden_inputs_max_pass'] and $config['spam']['hidden_inputs_expire'] to
|
||||||
|
* something higher to avoid false positives.
|
||||||
|
*
|
||||||
|
* See also: http://tinyboard.org/docs/?p=Your_request_looks_automated
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Number of hidden fields to generate
|
||||||
$config['spam']['hidden_inputs_min'] = 4;
|
$config['spam']['hidden_inputs_min'] = 4;
|
||||||
$config['spam']['hidden_inputs_max'] = 12;
|
$config['spam']['hidden_inputs_max'] = 12;
|
||||||
|
// How many times can a "hash" be used to post?
|
||||||
|
$config['spam']['hidden_inputs_max_pass'] = 30;
|
||||||
|
// How soon after regeneration do hashes expire (in seconds)?
|
||||||
|
$config['spam']['hidden_inputs_expire'] = 60 * 60 * 2; // two hours
|
||||||
// These are fields used to confuse the bots. Make sure they aren't actually used by Tinyboard, or it won't work.
|
// These are fields used to confuse the bots. Make sure they aren't actually used by Tinyboard, or it won't work.
|
||||||
$config['spam']['hidden_input_names'] = array(
|
$config['spam']['hidden_input_names'] = array(
|
||||||
'user',
|
'user',
|
||||||
|
@ -13,7 +13,6 @@ require_once 'inc/display.php';
|
|||||||
require_once 'inc/template.php';
|
require_once 'inc/template.php';
|
||||||
require_once 'inc/database.php';
|
require_once 'inc/database.php';
|
||||||
require_once 'inc/events.php';
|
require_once 'inc/events.php';
|
||||||
require_once 'inc/anti-bot.php';
|
|
||||||
require_once 'inc/lib/gettext/gettext.inc';
|
require_once 'inc/lib/gettext/gettext.inc';
|
||||||
|
|
||||||
// the user is not currently logged in as a moderator
|
// the user is not currently logged in as a moderator
|
||||||
@ -210,6 +209,11 @@ function _syslog($priority, $message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function create_antibot($board, $thread = null) {
|
||||||
|
require_once 'inc/anti-bot.php';
|
||||||
|
|
||||||
|
return _create_antibot($board, $thread);
|
||||||
|
}
|
||||||
|
|
||||||
function rebuildThemes($action) {
|
function rebuildThemes($action) {
|
||||||
// List themes
|
// List themes
|
||||||
@ -1175,6 +1179,7 @@ function buildIndex() {
|
|||||||
$content['pages'] = $pages;
|
$content['pages'] = $pages;
|
||||||
$content['pages'][$page-1]['selected'] = true;
|
$content['pages'][$page-1]['selected'] = true;
|
||||||
$content['btn'] = getPageButtons($content['pages']);
|
$content['btn'] = getPageButtons($content['pages']);
|
||||||
|
$content['antibot'] = create_antibot($board['uri']);
|
||||||
file_write($filename, Element('index.html', $content));
|
file_write($filename, Element('index.html', $content));
|
||||||
|
|
||||||
if(isset($md5) && $md5 == md5_file($filename)) {
|
if(isset($md5) && $md5 == md5_file($filename)) {
|
||||||
@ -1492,6 +1497,7 @@ function buildThread($id, $return=false, $mod=false) {
|
|||||||
'config' => $config,
|
'config' => $config,
|
||||||
'id' => $id,
|
'id' => $id,
|
||||||
'mod' => $mod,
|
'mod' => $mod,
|
||||||
|
'antibot' => $mod ? false : create_antibot($board['uri'], $id),
|
||||||
'boardlist' => createBoardlist($mod),
|
'boardlist' => createBoardlist($mod),
|
||||||
'return' => ($mod ? '?' . $board['url'] . $config['file_index'] : $config['root'] . $board['uri'] . '/' . $config['file_index'])
|
'return' => ($mod ? '?' . $board['url'] . $config['file_index'] : $config['root'] . $board['uri'] . '/' . $config['file_index'])
|
||||||
));
|
));
|
||||||
|
@ -24,7 +24,7 @@ function load_twig() {
|
|||||||
|
|
||||||
$loader = new Twig_Loader_Filesystem($config['dir']['template']);
|
$loader = new Twig_Loader_Filesystem($config['dir']['template']);
|
||||||
$loader->setPaths($config['dir']['template']);
|
$loader->setPaths($config['dir']['template']);
|
||||||
$twig = new Twig_Environment($loader, Array(
|
$twig = new Twig_Environment($loader, array(
|
||||||
'autoescape' => false,
|
'autoescape' => false,
|
||||||
'cache' => "{$config['dir']['template']}/cache",
|
'cache' => "{$config['dir']['template']}/cache",
|
||||||
'debug' => ($config['debug'] ? true : false),
|
'debug' => ($config['debug'] ? true : false),
|
||||||
|
13
install.php
13
install.php
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Installation/upgrade file
|
// Installation/upgrade file
|
||||||
define('VERSION', 'v0.9.6-dev-1');
|
define('VERSION', 'v0.9.6-dev-2');
|
||||||
|
|
||||||
require 'inc/functions.php';
|
require 'inc/functions.php';
|
||||||
|
|
||||||
@ -174,6 +174,17 @@ if(file_exists($config['has_installed'])) {
|
|||||||
CHANGE `uri` `uri` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
|
CHANGE `uri` `uri` VARCHAR( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
|
||||||
CHANGE `title` `title` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
|
CHANGE `title` `title` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
|
||||||
CHANGE `subtitle` `subtitle` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error());
|
CHANGE `subtitle` `subtitle` TINYTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL") or error(db_error());
|
||||||
|
case 'v0.9.6-dev-1':
|
||||||
|
query("CREATE TABLE IF NOT EXISTS `antispam` (
|
||||||
|
`board` varchar(255) NOT NULL,
|
||||||
|
`thread` int(11) DEFAULT NULL,
|
||||||
|
`hash` bigint(20) NOT NULL,
|
||||||
|
`created` int(11) NOT NULL,
|
||||||
|
`expires` int(11) DEFAULT NULL,
|
||||||
|
`passed` smallint(6) NOT NULL,
|
||||||
|
PRIMARY KEY (`hash`),
|
||||||
|
KEY `board` (`board`,`thread`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
|
||||||
case false:
|
case false:
|
||||||
// Update version number
|
// Update version number
|
||||||
file_write($config['has_installed'], VERSION);
|
file_write($config['has_installed'], VERSION);
|
||||||
|
17
install.sql
17
install.sql
@ -228,6 +228,23 @@ CREATE TABLE IF NOT EXISTS `cites` (
|
|||||||
KEY `post` (`board`,`post`)
|
KEY `post` (`board`,`post`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `antispam`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `antispam` (
|
||||||
|
`board` varchar(255) NOT NULL,
|
||||||
|
`thread` int(11) DEFAULT NULL,
|
||||||
|
`hash` bigint(20) NOT NULL,
|
||||||
|
`created` int(11) NOT NULL,
|
||||||
|
`expires` int(11) DEFAULT NULL,
|
||||||
|
`passed` smallint(6) NOT NULL,
|
||||||
|
PRIMARY KEY (`hash`),
|
||||||
|
KEY `board` (`board`,`thread`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||||
|
10
mod.php
10
mod.php
@ -9,7 +9,7 @@ require 'inc/mod.php';
|
|||||||
|
|
||||||
if (get_magic_quotes_gpc()) {
|
if (get_magic_quotes_gpc()) {
|
||||||
function strip_array($var) {
|
function strip_array($var) {
|
||||||
return is_array($var) ? array_map("strip_array", $var) : stripslashes($var);
|
return is_array($var) ? array_map('strip_array', $var) : stripslashes($var);
|
||||||
}
|
}
|
||||||
|
|
||||||
$_GET = strip_array($_GET);
|
$_GET = strip_array($_GET);
|
||||||
@ -1698,6 +1698,10 @@ if(!$mod) {
|
|||||||
$query->bindValue(':board', $board['uri']);
|
$query->bindValue(':board', $board['uri']);
|
||||||
$query->execute() or error(db_error($query));
|
$query->execute() or error(db_error($query));
|
||||||
|
|
||||||
|
$query = prepare("DELETE FROM `antispam` WHERE `board` = :board");
|
||||||
|
$query->bindValue(':board', $board['uri']);
|
||||||
|
$query->execute() or error(db_error($query));
|
||||||
|
|
||||||
$_board = $board;
|
$_board = $board;
|
||||||
|
|
||||||
rebuildThemes('boards');
|
rebuildThemes('boards');
|
||||||
@ -2209,7 +2213,6 @@ if(!$mod) {
|
|||||||
$page['pages'][$page_no-1]['selected'] = true;
|
$page['pages'][$page_no-1]['selected'] = true;
|
||||||
$page['btn'] = getPageButtons($page['pages'], true);
|
$page['btn'] = getPageButtons($page['pages'], true);
|
||||||
$page['mod'] = true;
|
$page['mod'] = true;
|
||||||
|
|
||||||
echo Element('index.html', $page);
|
echo Element('index.html', $page);
|
||||||
} elseif(preg_match('/^\/' . $regex['board'] . $regex['res'] . $regex['page'] . '$/', $query, $matches)) {
|
} elseif(preg_match('/^\/' . $regex['board'] . $regex['res'] . $regex['page'] . '$/', $query, $matches)) {
|
||||||
// View thread
|
// View thread
|
||||||
@ -2354,7 +2357,8 @@ if(!$mod) {
|
|||||||
if(!openBoard($boardName))
|
if(!openBoard($boardName))
|
||||||
error($config['error']['noboard']);
|
error($config['error']['noboard']);
|
||||||
|
|
||||||
if(!hasPermission($config['mod']['delete'], $boardName)) error($config['error']['noaccess']);
|
if(!hasPermission($config['mod']['delete'], $boardName))
|
||||||
|
error($config['error']['noaccess']);
|
||||||
|
|
||||||
$post = &$matches[2];
|
$post = &$matches[2];
|
||||||
|
|
||||||
|
43
post.php
43
post.php
@ -5,11 +5,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
require 'inc/functions.php';
|
require 'inc/functions.php';
|
||||||
|
require 'inc/anti-bot.php';
|
||||||
|
|
||||||
// Fix for magic quotes
|
// Fix for magic quotes
|
||||||
if (get_magic_quotes_gpc()) {
|
if (get_magic_quotes_gpc()) {
|
||||||
function strip_array($var) {
|
function strip_array($var) {
|
||||||
return is_array($var) ? array_map("strip_array", $var) : stripslashes($var);
|
return is_array($var) ? array_map('strip_array', $var) : stripslashes($var);
|
||||||
}
|
}
|
||||||
|
|
||||||
$_GET = strip_array($_GET);
|
$_GET = strip_array($_GET);
|
||||||
@ -192,7 +193,26 @@ if(isset($_POST['delete'])) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(checkSpam(array($board['uri'], isset($post['thread']) && !($config['quick_reply'] && isset($_POST['quick-reply'])) ? $post['thread'] : null)))
|
if($post['mod'] = isset($_POST['mod']) && $_POST['mod']) {
|
||||||
|
require 'inc/mod.php';
|
||||||
|
if(!$mod) {
|
||||||
|
// Liar. You're not a mod.
|
||||||
|
error($config['error']['notamod']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$post['sticky'] = $post['op'] && isset($_POST['sticky']);
|
||||||
|
$post['locked'] = $post['op'] && isset($_POST['lock']);
|
||||||
|
$post['raw'] = isset($_POST['raw']);
|
||||||
|
|
||||||
|
if($post['sticky'] && !hasPermission($config['mod']['sticky'], $board['uri']))
|
||||||
|
error($config['error']['noaccess']);
|
||||||
|
if($post['locked'] && !hasPermission($config['mod']['lock'], $board['uri']))
|
||||||
|
error($config['error']['noaccess']);
|
||||||
|
if($post['raw'] && !hasPermission($config['mod']['rawhtml'], $board['uri']))
|
||||||
|
error($config['error']['noaccess']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$post['mod'] && checkSpam(array($board['uri'], isset($post['thread']) && !($config['quick_reply'] && isset($_POST['quick-reply'])) ? $post['thread'] : null)))
|
||||||
error($config['error']['spam']);
|
error($config['error']['spam']);
|
||||||
|
|
||||||
if($config['robot_enable'] && $config['robot_mute']) {
|
if($config['robot_enable'] && $config['robot_mute']) {
|
||||||
@ -239,25 +259,6 @@ if(isset($_POST['delete'])) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($post['mod'] = isset($_POST['mod']) && $_POST['mod']) {
|
|
||||||
require 'inc/mod.php';
|
|
||||||
if(!$mod) {
|
|
||||||
// Liar. You're not a mod.
|
|
||||||
error($config['error']['notamod']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$post['sticky'] = $post['op'] && isset($_POST['sticky']);
|
|
||||||
$post['locked'] = $post['op'] && isset($_POST['lock']);
|
|
||||||
$post['raw'] = isset($_POST['raw']);
|
|
||||||
|
|
||||||
if($post['sticky'] && !hasPermission($config['mod']['sticky'], $board['uri']))
|
|
||||||
error($config['error']['noaccess']);
|
|
||||||
if($post['locked'] && !hasPermission($config['mod']['lock'], $board['uri']))
|
|
||||||
error($config['error']['noaccess']);
|
|
||||||
if($post['raw'] && !hasPermission($config['mod']['rawhtml'], $board['uri']))
|
|
||||||
error($config['error']['noaccess']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!hasPermission($config['mod']['bypass_field_disable'], $board['uri'])) {
|
if(!hasPermission($config['mod']['bypass_field_disable'], $board['uri'])) {
|
||||||
if($config['field_disable_name'])
|
if($config['field_disable_name'])
|
||||||
$_POST['name'] = $config['anonymous']; // "forced anonymous"
|
$_POST['name'] = $config['anonymous']; // "forced anonymous"
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
<form name="post" onsubmit="return dopost(this);" enctype="multipart/form-data" action="{{ config.post_url }}" method="post">
|
<form name="post" onsubmit="return dopost(this);" enctype="multipart/form-data" action="{{ config.post_url }}" method="post">
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
{% if id %}<input type="hidden" name="thread" value="{{ id }}">{% endif %}
|
{% if id %}<input type="hidden" name="thread" value="{{ id }}">{% endif %}
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
<input type="hidden" name="board" value="{{ board.uri }}">
|
<input type="hidden" name="board" value="{{ board.uri }}">
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
{% if mod %}<input type="hidden" name="mod" value="1">{% endif %}
|
{% if mod %}<input type="hidden" name="mod" value="1">{% endif %}
|
||||||
<table>
|
<table>
|
||||||
{% if not config.field_disable_name or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}<tr>
|
{% if not config.field_disable_name or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}<tr>
|
||||||
<th>
|
<th>
|
||||||
{% trans %}Name{% endtrans %}
|
{% trans %}Name{% endtrans %}
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="name" size="25" maxlength="50" autocomplete="off">
|
<input type="text" name="name" size="25" maxlength="50" autocomplete="off">
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</td>
|
</td>
|
||||||
</tr>{% endif %}
|
</tr>{% endif %}
|
||||||
{% if not config.field_disable_email or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}<tr>
|
{% if not config.field_disable_email or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}<tr>
|
||||||
<th>
|
<th>
|
||||||
{% trans %}Email{% endtrans %}
|
{% trans %}Email{% endtrans %}
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="email" size="25" maxlength="40" autocomplete="off">
|
<input type="text" name="email" size="25" maxlength="40" autocomplete="off">
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</td>
|
</td>
|
||||||
</tr>{% endif %}
|
</tr>{% endif %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
{% trans %}Subject{% endtrans %}
|
{% trans %}Subject{% endtrans %}
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<input style="float:left;" type="text" name="subject" size="25" maxlength="100" autocomplete="off">
|
<input style="float:left;" type="text" name="subject" size="25" maxlength="100" autocomplete="off">
|
||||||
@ -39,22 +39,22 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
{% trans %}Comment{% endtrans %}
|
{% trans %}Comment{% endtrans %}
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<textarea name="body" id="body" rows="5" cols="35"></textarea>
|
<textarea name="body" id="body" rows="5" cols="35"></textarea>
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% if config.recaptcha %}
|
{% if config.recaptcha %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
{% trans %}Verification{% endtrans %}
|
{% trans %}Verification{% endtrans %}
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<script type="text/javascript" src="http://www.google.com/recaptcha/api/challenge?k={{ config.recaptcha_public }}"></script>
|
<script type="text/javascript" src="http://www.google.com/recaptcha/api/challenge?k={{ config.recaptcha_public }}"></script>
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -64,18 +64,18 @@
|
|||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="file" name="file">
|
<input type="file" name="file">
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% if config.enable_embedding %}
|
{% if config.enable_embedding %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
{% trans %}Embed{% endtrans %}
|
{% trans %}Embed{% endtrans %}
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="embed" size="30" maxlength="120" autocomplete="off">
|
<input type="text" name="embed" size="30" maxlength="120" autocomplete="off">
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -103,18 +103,17 @@
|
|||||||
{% if not config.field_disable_password or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}<tr>
|
{% if not config.field_disable_password or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}<tr>
|
||||||
<th>
|
<th>
|
||||||
{% trans %}Password{% endtrans %}
|
{% trans %}Password{% endtrans %}
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="password" name="password" size="12" maxlength="18" autocomplete="off">
|
<input type="password" name="password" size="12" maxlength="18" autocomplete="off">
|
||||||
<span class="unimportant">{% trans %}(For file deletion.){% endtrans %}</span>
|
<span class="unimportant">{% trans %}(For file deletion.){% endtrans %}</span>
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html() }}
|
||||||
</td>
|
</td>
|
||||||
</tr>{% endif %}
|
</tr>{% endif %}
|
||||||
</table>
|
</table>
|
||||||
{{ hiddenInputs([board.uri, id]) }}
|
{{ antibot.html(true) }}
|
||||||
<input type="hidden" name="hash" value="{{ hiddenInputsHash([board.uri, id]) }}">
|
<input type="hidden" name="hash" value="{{ antibot.hash() }}">
|
||||||
{{ hiddenInputs([board.uri, id], true) }}
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script type="text/javascript">{% raw %}
|
<script type="text/javascript">{% raw %}
|
||||||
|
Loading…
Reference in New Issue
Block a user