mirror of
https://github.com/vichan-devel/vichan.git
synced 2024-11-28 01:10:51 +01:00
commit
39715e3595
357
inc/captcha/captcha.php
Normal file
357
inc/captcha/captcha.php
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
<?php
|
||||||
|
class CzaksCaptcha {
|
||||||
|
var $content = array();
|
||||||
|
|
||||||
|
var $width, $height, $color, $charset, $style;
|
||||||
|
|
||||||
|
function __construct($text, $left, $top, $charset=false) {
|
||||||
|
if (!$charset) {
|
||||||
|
$charset = 'abcdefghijklmnopqrstuvwxyz';
|
||||||
|
}
|
||||||
|
|
||||||
|
$len = mb_strlen($text, 'utf-8');
|
||||||
|
|
||||||
|
$this->width = $left;
|
||||||
|
$this->height = $top;
|
||||||
|
|
||||||
|
$this->charset = preg_split('//u', $charset);
|
||||||
|
|
||||||
|
$this->style = "";
|
||||||
|
|
||||||
|
for ($i = 0; $i < $len; $i++) {
|
||||||
|
$this->content[] = array(mb_substr($text, $i, 1, 'utf-8'), "top" => $top / 2 - $top / 4,
|
||||||
|
"left" => $left/10 + 9*$left*$i/10/$len,
|
||||||
|
"position" => "absolute");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->color = "hsla(".rand(1,360).", 76%, 78%, 1)";
|
||||||
|
|
||||||
|
$this->add_junk();
|
||||||
|
$this->mutate_sizes();
|
||||||
|
$this->mutate_positions();
|
||||||
|
$this->mutate_transform();
|
||||||
|
$this->mutate_anchors();
|
||||||
|
$this->randomize();
|
||||||
|
$this->mutate_containers();
|
||||||
|
$this->mutate_margins();
|
||||||
|
$this->mutate_styles();
|
||||||
|
$this->randomize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mutate_sizes() {
|
||||||
|
foreach ($this->content as &$v) {
|
||||||
|
if (!isset ($v['font-size']))
|
||||||
|
$v['font-size'] = rand($this->height/3 - 4, $this->height/3 + 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function mutate_positions() {
|
||||||
|
foreach ($this->content as &$v) {
|
||||||
|
$v['top'] += rand(-10,10);
|
||||||
|
$v['left'] += rand(-10,10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function mutate_transform() {
|
||||||
|
$fromto = array('6'=>'9', '9'=>'6', '8'=>'8', '0'=>'0',
|
||||||
|
'z'=>'z', 's'=>'s', 'n'=>'u', 'u'=>'n',
|
||||||
|
'a'=>'ɐ', 'e'=>'ə', 'p'=>'d', 'd'=>'p',
|
||||||
|
'A'=>'∀', 'E'=>'∃', 'H'=>'H', 'o'=>'o',
|
||||||
|
'O'=>'O');
|
||||||
|
|
||||||
|
foreach ($this->content as &$v) {
|
||||||
|
$basefrom = -20;
|
||||||
|
$baseto = 20;
|
||||||
|
|
||||||
|
if (isset($fromto[$v[0]]) && rand(0,1)) {
|
||||||
|
$v[0] = $fromto[$v[0]];
|
||||||
|
$basefrom = 160;
|
||||||
|
$baseto = 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
$v['transform'] = 'rotate('.rand($basefrom,$baseto).'deg)';
|
||||||
|
$v['-ms-transform'] = 'rotate('.rand($basefrom,$baseto).'deg)';
|
||||||
|
$v['-webkit-transform'] = 'rotate('.rand($basefrom,$baseto).'deg)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function randomize(&$a = false) {
|
||||||
|
if ($a === false) {
|
||||||
|
$a = &$this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
shuffle($a);
|
||||||
|
|
||||||
|
foreach ($a as &$v) {
|
||||||
|
$this->shuffle_assoc($v);
|
||||||
|
|
||||||
|
if (is_array ($v[0])) {
|
||||||
|
$this->randomize($v[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_junk() {
|
||||||
|
$count = rand(200, 300);
|
||||||
|
|
||||||
|
while ($count--) {
|
||||||
|
$elem = array();
|
||||||
|
|
||||||
|
$elem['top'] = rand(0, $this->height);
|
||||||
|
$elem['left'] = rand(0, $this->width);
|
||||||
|
|
||||||
|
$elem['position'] = 'absolute';
|
||||||
|
|
||||||
|
$elem[0] = $this->charset[rand(0, count($this->charset)-1)];
|
||||||
|
|
||||||
|
switch($t = rand (0,9)) {
|
||||||
|
case 0:
|
||||||
|
$elem['display'] = 'none'; break;
|
||||||
|
case 1:
|
||||||
|
$elem['top'] = rand(-60, -90); break;
|
||||||
|
case 2:
|
||||||
|
$elem['left'] = rand(-40, -70); break;
|
||||||
|
case 3:
|
||||||
|
$elem['top'] = $this->height + rand(10, 60); break;
|
||||||
|
case 4:
|
||||||
|
$elem['left'] = $this->width + rand(10, 60); break;
|
||||||
|
case 5:
|
||||||
|
$elem['color'] = $this->color; break;
|
||||||
|
case 6:
|
||||||
|
$elem['visibility'] = 'hidden'; break;
|
||||||
|
case 7:
|
||||||
|
$elem['height'] = rand(0,2);
|
||||||
|
$elem['overflow'] = 'hidden'; break;
|
||||||
|
case 8:
|
||||||
|
$elem['width'] = rand(0,1);
|
||||||
|
$elem['overflow'] = 'hidden'; break;
|
||||||
|
case 9:
|
||||||
|
$elem['font-size'] = rand(2, 6); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->content[] = $elem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mutate_anchors() {
|
||||||
|
foreach ($this->content as &$elem) {
|
||||||
|
if (rand(0,1)) {
|
||||||
|
$elem['right'] = $this->width - $elem['left'] - (int)(0.5*$elem['font-size']);
|
||||||
|
unset($elem['left']);
|
||||||
|
}
|
||||||
|
if (rand(0,1)) {
|
||||||
|
$elem['bottom'] = $this->height - $elem['top'] - (int)(1.5*$elem['font-size']);
|
||||||
|
unset($elem['top']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mutate_containers() {
|
||||||
|
for ($i = 0; $i <= 80; $i++) {
|
||||||
|
$new = [];
|
||||||
|
$new['width'] = rand(0, $this->width*2);
|
||||||
|
$new['height'] = rand(0, $this->height*2);
|
||||||
|
$new['top'] = rand(-$this->height * 2, $this->height * 2);
|
||||||
|
$new['bottom'] = $this->height - ($new['top'] + $new['height']);
|
||||||
|
$new['left'] = rand(-$this->width * 2, $this->width * 2);
|
||||||
|
$new['right'] = $this->width - ($new['left'] + $new['width']);
|
||||||
|
|
||||||
|
$new['position'] = 'absolute';
|
||||||
|
|
||||||
|
$new[0] = [];
|
||||||
|
|
||||||
|
$cnt = rand(0,10);
|
||||||
|
for ($j = 0; $j < $cnt; $j++) {
|
||||||
|
$elem = array_pop($this->content);
|
||||||
|
if (!$elem) break;
|
||||||
|
|
||||||
|
if (isset($elem['top'])) $elem['top'] -= $new['top'];
|
||||||
|
if (isset($elem['bottom'])) $elem['bottom'] -= $new['bottom'];
|
||||||
|
if (isset($elem['left'])) $elem['left'] -= $new['left'];
|
||||||
|
if (isset($elem['right'])) $elem['right'] -= $new['right'];
|
||||||
|
|
||||||
|
$new[0][] = $elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rand (0,1)) unset($new['top']);
|
||||||
|
else unset($new['bottom']);
|
||||||
|
if (rand (0,1)) unset($new['left']);
|
||||||
|
else unset($new['right']);
|
||||||
|
|
||||||
|
$this->content[] = $new;
|
||||||
|
|
||||||
|
shuffle($this->content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mutate_margins(&$a = false) {
|
||||||
|
if ($a === false) {
|
||||||
|
$a = &$this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($a as &$v) {
|
||||||
|
$ary = ['top', 'left', 'bottom', 'right'];
|
||||||
|
shuffle($ary);
|
||||||
|
$cnt = rand(0,4);
|
||||||
|
$ary = array_slice($ary, 0, $cnt);
|
||||||
|
|
||||||
|
foreach ($ary as $prop) {
|
||||||
|
$margin = rand(-1000, 1000);
|
||||||
|
|
||||||
|
$v['margin-'.$prop] = $margin;
|
||||||
|
|
||||||
|
if (isset($v[$prop])) {
|
||||||
|
$v[$prop] -= $margin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($v[0])) {
|
||||||
|
$this->mutate_margins($v[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mutate_styles(&$a = false) {
|
||||||
|
if ($a === false) {
|
||||||
|
$a = &$this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($a as &$v) {
|
||||||
|
$content = $v[0];
|
||||||
|
unset($v[0]);
|
||||||
|
$styles = array_splice($v, 0, rand(0, 6));
|
||||||
|
$v[0] = $content;
|
||||||
|
|
||||||
|
$id_or_class = rand(0,1);
|
||||||
|
$param = $id_or_class ? "id" : "class";
|
||||||
|
$prefix = $id_or_class ? "#" : ".";
|
||||||
|
$genname = "zz-".base_convert(rand(1,999999999), 10, 36);
|
||||||
|
|
||||||
|
if ($styles || rand(0,1)) {
|
||||||
|
$this->style .= $prefix.$genname."{";
|
||||||
|
$this->style .= $this->rand_whitespace();
|
||||||
|
|
||||||
|
foreach ($styles as $k => $val) {
|
||||||
|
if (is_int($val)) {
|
||||||
|
$val = "".$val."px";
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->style .= "$k:";
|
||||||
|
$this->style .= $this->rand_whitespace();
|
||||||
|
$this->style .= "$val;";
|
||||||
|
$this->style .= $this->rand_whitespace();
|
||||||
|
}
|
||||||
|
$this->style .= "}";
|
||||||
|
$this->style .= $this->rand_whitespace();
|
||||||
|
}
|
||||||
|
|
||||||
|
$v[$param] = $genname;
|
||||||
|
|
||||||
|
if (is_array($v[0])) {
|
||||||
|
$this->mutate_styles($v[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function to_html(&$a = false) {
|
||||||
|
$inside = true;
|
||||||
|
|
||||||
|
if ($a === false) {
|
||||||
|
if ($this->style) {
|
||||||
|
echo "<style type='text/css'>";
|
||||||
|
echo $this->style;
|
||||||
|
echo "</style>";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "<div style='position: relative; width: ".$this->width."px; height: ".$this->height."px; overflow: hidden; background-color: ".$this->color."'>";
|
||||||
|
$a = &$this->content;
|
||||||
|
$inside = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($a as &$v) {
|
||||||
|
$letter = $v[0];
|
||||||
|
|
||||||
|
unset ($v[0]);
|
||||||
|
|
||||||
|
echo "<div";
|
||||||
|
echo $this->rand_whitespace(1);
|
||||||
|
|
||||||
|
if (isset ($v['id'])) {
|
||||||
|
echo "id='$v[id]'";
|
||||||
|
echo $this->rand_whitespace(1);
|
||||||
|
|
||||||
|
unset ($v['id']);
|
||||||
|
}
|
||||||
|
if (isset ($v['class'])) {
|
||||||
|
echo "class='$v[class]'";
|
||||||
|
echo $this->rand_whitespace(1);
|
||||||
|
|
||||||
|
unset ($v['class']);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "style='";
|
||||||
|
|
||||||
|
foreach ($v as $k => $val) {
|
||||||
|
if (is_int($val)) {
|
||||||
|
$val = "".$val."px";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "$k:";
|
||||||
|
echo $this->rand_whitespace();
|
||||||
|
echo "$val;";
|
||||||
|
echo $this->rand_whitespace();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "'>";
|
||||||
|
echo $this->rand_whitespace();
|
||||||
|
|
||||||
|
if (is_array ($letter)) {
|
||||||
|
$this->to_html($letter);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo $letter;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$inside) {
|
||||||
|
echo "</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function rand_whitespace($r = 0) {
|
||||||
|
switch (rand($r,4)) {
|
||||||
|
case 0:
|
||||||
|
return "";
|
||||||
|
case 1:
|
||||||
|
return "\n";
|
||||||
|
case 2:
|
||||||
|
return "\t";
|
||||||
|
case 3:
|
||||||
|
return " ";
|
||||||
|
case 4:
|
||||||
|
return " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function shuffle_assoc(&$array) {
|
||||||
|
$keys = array_keys($array);
|
||||||
|
|
||||||
|
shuffle($keys);
|
||||||
|
|
||||||
|
foreach($keys as $key) {
|
||||||
|
$new[$key] = $array[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
$array = $new;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//$charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789卐";
|
||||||
|
|
||||||
|
//(new CzaksCaptcha("hotwheels", 300, 80, $charset))->to_html();
|
||||||
|
?>
|
16
inc/captcha/config.php
Normal file
16
inc/captcha/config.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
// We are using a custom path here to connect to the database.
|
||||||
|
// Why? Performance reasons.
|
||||||
|
|
||||||
|
$pdo = new PDO("mysql:dbname=database_name;host=localhost", "database_user", "database_password", array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
|
||||||
|
|
||||||
|
|
||||||
|
// Captcha expiration:
|
||||||
|
$expires_in = 120; // 120 seconds
|
||||||
|
|
||||||
|
// Captcha dimensions:
|
||||||
|
$width = 250;
|
||||||
|
$height = 80;
|
||||||
|
|
||||||
|
// Captcha length:
|
||||||
|
$length = 6;
|
9
inc/captcha/dbschema.sql
Normal file
9
inc/captcha/dbschema.sql
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
SET NAMES utf8;
|
||||||
|
|
||||||
|
CREATE TABLE `captchas` (
|
||||||
|
`cookie` VARCHAR(50),
|
||||||
|
`extra` VARCHAR(200),
|
||||||
|
`text` VARCHAR(255),
|
||||||
|
`created_at` INT(11),
|
||||||
|
PRIMARY KEY (cookie, extra)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
|
85
inc/captcha/entrypoint.php
Normal file
85
inc/captcha/entrypoint.php
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
$mode = @$_GET['mode'];
|
||||||
|
|
||||||
|
require_once("captcha.php");
|
||||||
|
|
||||||
|
function rand_string($length, $charset) {
|
||||||
|
$ret = "";
|
||||||
|
while ($length--) {
|
||||||
|
$ret .= mb_substr($charset, rand(0, mb_strlen($charset, 'utf-8')-1), 1, 'utf-8');
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanup ($pdo, $expires_in) {
|
||||||
|
$pdo->prepare("DELETE FROM `captchas` WHERE `created_at` < ?")->execute([time() - $expires_in]);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($mode) {
|
||||||
|
// Request: GET entrypoint.php?mode=get&extra=1234567890
|
||||||
|
// Response: JSON: cookie => "generatedcookie", captchahtml => "captchahtml", expires_in => 120
|
||||||
|
case "get":
|
||||||
|
if (!isset ($_GET['extra'])) {
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
header("Content-type: application/json");
|
||||||
|
|
||||||
|
$extra = $_GET['extra'];
|
||||||
|
|
||||||
|
require_once("config.php");
|
||||||
|
|
||||||
|
$text = rand_string($length, $extra);
|
||||||
|
|
||||||
|
$captcha = new CzaksCaptcha($text, $width, $height, $extra);
|
||||||
|
|
||||||
|
$cookie = rand_string(20, "abcdefghijklmnopqrstuvwxyz");
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
$captcha->to_html();
|
||||||
|
$html = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
$query = $pdo->prepare("INSERT INTO `captchas` (`cookie`, `extra`, `text`, `created_at`) VALUES (?, ?, ?, ?)");
|
||||||
|
$query->execute( [$cookie, $extra, $text, time()]);
|
||||||
|
|
||||||
|
echo json_encode(["cookie" => $cookie, "captchahtml" => $html, "expires_in" => $expires_in]);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Request: GET entrypoint.php?mode=check&cookie=generatedcookie&extra=1234567890&text=captcha
|
||||||
|
// Response: 0 OR 1
|
||||||
|
case "check":
|
||||||
|
if (!isset ($_GET['mode'])
|
||||||
|
|| !isset ($_GET['cookie'])
|
||||||
|
|| !isset ($_GET['extra'])
|
||||||
|
|| !isset ($_GET['text'])) {
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once("config.php");
|
||||||
|
|
||||||
|
cleanup($pdo, $expires_in);
|
||||||
|
|
||||||
|
$query = $pdo->prepare("SELECT * FROM `captchas` WHERE `cookie` = ? AND `extra` = ?");
|
||||||
|
$query->execute([$_GET['cookie'], $_GET['extra']]);
|
||||||
|
|
||||||
|
$ary = $query->fetchAll();
|
||||||
|
|
||||||
|
if (!$ary) {
|
||||||
|
echo "0";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$query = $pdo->prepare("DELETE FROM `captchas` WHERE `cookie` = ? AND `extra` = ?");
|
||||||
|
$query->execute([$_GET['cookie'], $_GET['extra']]);
|
||||||
|
|
||||||
|
if ($ary[0]['text'] !== $_GET['text']) {
|
||||||
|
echo "0";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo "1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
10
inc/captcha/readme.md
Normal file
10
inc/captcha/readme.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
I integrated this from: https://github.com/ctrlcctrlv/infinity/commit/62a6dac022cb338f7b719d0c35a64ab3efc64658
|
||||||
|
|
||||||
|
<strike>First import the captcha/dbschema.sql in your database</strike> it is no longer required.
|
||||||
|
|
||||||
|
In inc/captcha/config.php change the database_name database_user database_password to your own settings.
|
||||||
|
|
||||||
|
Add js/captcha.js in your instance-config.php or config.php
|
||||||
|
|
||||||
|
Go to Line 305 in the /inc/config file and copy the settings in instance config, while changing the url to your website.
|
||||||
|
Go to the line beneath it if you only want to enable it when posting a new thread.
|
@ -288,6 +288,8 @@
|
|||||||
'embed',
|
'embed',
|
||||||
'recaptcha_challenge_field',
|
'recaptcha_challenge_field',
|
||||||
'recaptcha_response_field',
|
'recaptcha_response_field',
|
||||||
|
'captcha_cookie',
|
||||||
|
'captcha_text',
|
||||||
'spoiler',
|
'spoiler',
|
||||||
'page',
|
'page',
|
||||||
'file_url',
|
'file_url',
|
||||||
@ -303,6 +305,26 @@
|
|||||||
// Public and private key pair from https://www.google.com/recaptcha/admin/create
|
// Public and private key pair from https://www.google.com/recaptcha/admin/create
|
||||||
$config['recaptcha_public'] = '6LcXTcUSAAAAAKBxyFWIt2SO8jwx4W7wcSMRoN3f';
|
$config['recaptcha_public'] = '6LcXTcUSAAAAAKBxyFWIt2SO8jwx4W7wcSMRoN3f';
|
||||||
$config['recaptcha_private'] = '6LcXTcUSAAAAAOGVbVdhmEM1_SyRF4xTKe8jbzf_';
|
$config['recaptcha_private'] = '6LcXTcUSAAAAAOGVbVdhmEM1_SyRF4xTKe8jbzf_';
|
||||||
|
|
||||||
|
// Enable Custom Captcha you need to change a couple of settings
|
||||||
|
//Read more at: /captcha/instructions.md
|
||||||
|
$config['captcha'] = array();
|
||||||
|
|
||||||
|
// Enable custom captcha provider
|
||||||
|
$config['captcha']['enabled'] = false;
|
||||||
|
|
||||||
|
//New thread captcha
|
||||||
|
//Require solving a captcha to post a thread.
|
||||||
|
//Default off.
|
||||||
|
$config['new_thread_capt'] = false;
|
||||||
|
|
||||||
|
// Custom captcha get provider path (if not working get the absolute path aka your url.)
|
||||||
|
$config['captcha']['provider_get'] = '../inc/captcha/entrypoint.php';
|
||||||
|
// Custom captcha check provider path
|
||||||
|
$config['captcha']['provider_check'] = '../inc/captcha/entrypoint.php';
|
||||||
|
|
||||||
|
// Custom captcha extra field (eg. charset)
|
||||||
|
$config['captcha']['extra'] = 'abcdefghijklmnopqrstuvwxyz';
|
||||||
|
|
||||||
// Ability to lock a board for normal users and still allow mods to post. Could also be useful for making an archive board
|
// Ability to lock a board for normal users and still allow mods to post. Could also be useful for making an archive board
|
||||||
$config['board_locked'] = false;
|
$config['board_locked'] = false;
|
||||||
@ -1019,6 +1041,7 @@
|
|||||||
// $config['additional_javascript'][] = 'js/auto-reload.js';
|
// $config['additional_javascript'][] = 'js/auto-reload.js';
|
||||||
// $config['additional_javascript'][] = 'js/post-hover.js';
|
// $config['additional_javascript'][] = 'js/post-hover.js';
|
||||||
// $config['additional_javascript'][] = 'js/style-select.js';
|
// $config['additional_javascript'][] = 'js/style-select.js';
|
||||||
|
// $config['additional_javascript'][] = 'js/captcha.js';
|
||||||
|
|
||||||
// Where these script files are located on the web. Defaults to $config['root'].
|
// Where these script files are located on the web. Defaults to $config['root'].
|
||||||
// $config['additional_javascript_url'] = 'http://static.example.org/tinyboard-javascript-stuff/';
|
// $config['additional_javascript_url'] = 'http://static.example.org/tinyboard-javascript-stuff/';
|
||||||
|
15
install.php
15
install.php
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Installation/upgrade file
|
// Installation/upgrade file
|
||||||
define('VERSION', '5.1.3');
|
define('VERSION', '5.1.4');
|
||||||
|
|
||||||
require 'inc/functions.php';
|
require 'inc/functions.php';
|
||||||
|
|
||||||
@ -560,7 +560,7 @@ if (file_exists($config['has_installed'])) {
|
|||||||
query('ALTER TABLE ``mods`` CHANGE `salt` `version` VARCHAR(64) NOT NULL;') or error(db_error());
|
query('ALTER TABLE ``mods`` CHANGE `salt` `version` VARCHAR(64) NOT NULL;') or error(db_error());
|
||||||
case '5.0.1':
|
case '5.0.1':
|
||||||
case '5.1.0':
|
case '5.1.0':
|
||||||
query('CREATE TABLE ``pages`` (
|
query('CREATE TABLE IF NOT EXISTS ``pages`` (
|
||||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
`board` varchar(255) DEFAULT NULL,
|
`board` varchar(255) DEFAULT NULL,
|
||||||
`name` varchar(255) NOT NULL,
|
`name` varchar(255) NOT NULL,
|
||||||
@ -575,7 +575,7 @@ if (file_exists($config['has_installed'])) {
|
|||||||
query(sprintf("ALTER TABLE ``posts_%s`` ADD `cycle` int(1) NOT NULL AFTER `locked`", $board['uri'])) or error(db_error());
|
query(sprintf("ALTER TABLE ``posts_%s`` ADD `cycle` int(1) NOT NULL AFTER `locked`", $board['uri'])) or error(db_error());
|
||||||
}
|
}
|
||||||
case '5.1.2':
|
case '5.1.2':
|
||||||
query('CREATE TABLE ``nntp_references`` (
|
query('CREATE TABLE IF NOT EXISTS ``nntp_references`` (
|
||||||
`board` varchar(60) NOT NULL,
|
`board` varchar(60) NOT NULL,
|
||||||
`id` int(11) unsigned NOT NULL,
|
`id` int(11) unsigned NOT NULL,
|
||||||
`message_id` varchar(255) CHARACTER SET ascii NOT NULL,
|
`message_id` varchar(255) CHARACTER SET ascii NOT NULL,
|
||||||
@ -587,7 +587,14 @@ if (file_exists($config['has_installed'])) {
|
|||||||
UNIQUE KEY `u_board_id` (`board`, `id`)
|
UNIQUE KEY `u_board_id` (`board`, `id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
') or error(db_error());
|
') or error(db_error());
|
||||||
|
case '5.1.3':
|
||||||
|
query('CREATE TABLE IF NOT EXISTS ``captchas`` (
|
||||||
|
`cookie` varchar(50),
|
||||||
|
`extra` varchar(200),
|
||||||
|
`text` varchar(255),
|
||||||
|
`created_at` int(11),
|
||||||
|
PRIMARY KEY (`cookie`,`extra`),
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;') or error(db_error());
|
||||||
case false:
|
case false:
|
||||||
// TODO: enhance Tinyboard -> vichan upgrade path.
|
// TODO: enhance Tinyboard -> vichan upgrade path.
|
||||||
query("CREATE TABLE IF NOT EXISTS ``search_queries`` ( `ip` varchar(39) NOT NULL, `time` int(11) NOT NULL, `query` text NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8;") or error(db_error());
|
query("CREATE TABLE IF NOT EXISTS ``search_queries`` ( `ip` varchar(39) NOT NULL, `time` int(11) NOT NULL, `query` text NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8;") or error(db_error());
|
||||||
|
18
install.sql
18
install.sql
@ -303,7 +303,7 @@ CREATE TABLE IF NOT EXISTS `ban_appeals` (
|
|||||||
-- Table structure for table `pages`
|
-- Table structure for table `pages`
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE TABLE `pages` (
|
CREATE TABLE IF NOT EXISTS `pages` (
|
||||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
`board` varchar(58) CHARACTER SET utf8 DEFAULT NULL,
|
`board` varchar(58) CHARACTER SET utf8 DEFAULT NULL,
|
||||||
`name` varchar(255) CHARACTER SET utf8 NOT NULL,
|
`name` varchar(255) CHARACTER SET utf8 NOT NULL,
|
||||||
@ -320,7 +320,7 @@ CREATE TABLE `pages` (
|
|||||||
-- Table structure for table `nntp_references`
|
-- Table structure for table `nntp_references`
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE TABLE `nntp_references` (
|
CREATE TABLE IF NOT EXISTS `nntp_references` (
|
||||||
`board` varchar(30) NOT NULL,
|
`board` varchar(30) NOT NULL,
|
||||||
`id` int(11) unsigned NOT NULL,
|
`id` int(11) unsigned NOT NULL,
|
||||||
`message_id` varchar(255) CHARACTER SET ascii NOT NULL,
|
`message_id` varchar(255) CHARACTER SET ascii NOT NULL,
|
||||||
@ -332,6 +332,20 @@ CREATE TABLE `nntp_references` (
|
|||||||
UNIQUE KEY `u_board_id` (`board`, `id`)
|
UNIQUE KEY `u_board_id` (`board`, `id`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `captchas`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `captchas` (
|
||||||
|
`cookie` VARCHAR(50),
|
||||||
|
`extra` VARCHAR(200),
|
||||||
|
`text` VARCHAR(255),
|
||||||
|
`created_at` INT(11),
|
||||||
|
PRIMARY KEY (`cookie`,`extra`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
|
||||||
/*!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 */;
|
||||||
|
43
js/captcha.js
Normal file
43
js/captcha.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
var tout;
|
||||||
|
|
||||||
|
function redo_events(provider, extra) {
|
||||||
|
$('.captcha .captcha_text, textarea[id="body"]').off("focus").one("focus", function() { actually_load_captcha(provider, extra); });
|
||||||
|
}
|
||||||
|
|
||||||
|
function actually_load_captcha(provider, extra) {
|
||||||
|
$('.captcha .captcha_text, textarea[id="body"]').off("focus");
|
||||||
|
|
||||||
|
if (tout !== undefined) {
|
||||||
|
clearTimeout(tout);
|
||||||
|
}
|
||||||
|
|
||||||
|
$.getJSON(provider, {mode: 'get', extra: extra}, function(json) {
|
||||||
|
$(".captcha .captcha_cookie").val(json.cookie);
|
||||||
|
$(".captcha .captcha_html").html(json.captchahtml);
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
redo_events(provider, extra);
|
||||||
|
}, json.expires_in * 1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function load_captcha(provider, extra) {
|
||||||
|
$(function() {
|
||||||
|
$(".captcha>td").html("<input class='captcha_text' type='text' name='captcha_text' size='32' maxlength='6' autocomplete='off'>"+
|
||||||
|
"<input class='captcha_cookie' name='captcha_cookie' type='hidden'>"+
|
||||||
|
"<div class='captcha_html'></div>");
|
||||||
|
|
||||||
|
$("#quick-reply .captcha .captcha_text").prop("placeholder", _("Verification"));
|
||||||
|
|
||||||
|
$(".captcha .captcha_html").on("click", function() { actually_load_captcha(provider, extra); });
|
||||||
|
$(document).on("ajax_after_post", function() { actually_load_captcha(provider, extra); });
|
||||||
|
redo_events(provider, extra);
|
||||||
|
|
||||||
|
$(window).on("quick-reply", function() {
|
||||||
|
redo_events(provider, extra);
|
||||||
|
$("#quick-reply .captcha .captcha_html").html($("form:not(#quick-reply) .captcha .captcha_html").html());
|
||||||
|
$("#quick-reply .captcha .captcha_cookie").val($("form:not(#quick-reply) .captcha .captcha_cookie").html());
|
||||||
|
$("#quick-reply .captcha .captcha_html").on("click", function() { actually_load_captcha(provider, extra); });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -281,7 +281,7 @@
|
|||||||
|
|
||||||
$postForm.find('textarea[name="body"]').removeAttr('id').removeAttr('cols').attr('placeholder', _('Comment'));
|
$postForm.find('textarea[name="body"]').removeAttr('id').removeAttr('cols').attr('placeholder', _('Comment'));
|
||||||
|
|
||||||
$postForm.find('textarea:not([name="body"]),input[type="hidden"]').removeAttr('id').appendTo($dummyStuff);
|
$postForm.find('textarea:not([name="body"]),input[type="hidden"]:not(.captcha_cookie)').removeAttr('id').appendTo($dummyStuff);
|
||||||
|
|
||||||
$postForm.find('br').remove();
|
$postForm.find('br').remove();
|
||||||
$postForm.find('table').prepend('<tr><th colspan="2">\
|
$postForm.find('table').prepend('<tr><th colspan="2">\
|
||||||
|
13
post.php
13
post.php
@ -393,7 +393,20 @@ if (isset($_POST['delete'])) {
|
|||||||
if (!$resp->is_valid) {
|
if (!$resp->is_valid) {
|
||||||
error($config['error']['captcha']);
|
error($config['error']['captcha']);
|
||||||
}
|
}
|
||||||
|
// Same, but now with our custom captcha provider
|
||||||
|
if (($config['captcha']['enabled']) || (($post['op']) && ($config['new_thread_capt'])) ) {
|
||||||
|
$resp = file_get_contents($config['captcha']['provider_check'] . "?" . http_build_query([
|
||||||
|
'mode' => 'check',
|
||||||
|
'text' => $_POST['captcha_text'],
|
||||||
|
'extra' => $config['captcha']['extra'],
|
||||||
|
'cookie' => $_POST['captcha_cookie']
|
||||||
|
]));
|
||||||
|
if ($resp !== '1') {
|
||||||
|
error($config['error']['captcha'] .
|
||||||
|
'<script>if (actually_load_captcha !== undefined) actually_load_captcha("'.$config['captcha']['provider_get'].'", "'.$config['captcha']['extra'].'");</script>');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(($post['op'] && $_POST['post'] == $config['button_newtopic']) ||
|
if (!(($post['op'] && $_POST['post'] == $config['button_newtopic']) ||
|
||||||
(!$post['op'] && $_POST['post'] == $config['button_reply'])))
|
(!$post['op'] && $_POST['post'] == $config['button_reply'])))
|
||||||
|
@ -79,6 +79,27 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if config.captcha.enabled %}
|
||||||
|
<tr class='captcha'>
|
||||||
|
<th>
|
||||||
|
{% trans %}Verification{% endtrans %}
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<script>load_captcha("{{ config.captcha.provider_get }}", "{{ config.captcha.extra }}");</script>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% elseif config.new_thread_capt %}
|
||||||
|
{% if not id %}
|
||||||
|
<tr class='captcha'>
|
||||||
|
<th>
|
||||||
|
{% trans %}Verification{% endtrans %}
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<script>load_captcha("{{ config.captcha.provider_get }}", "{{ config.captcha.extra }}");</script>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
{% if config.user_flag %}
|
{% if config.user_flag %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans %}Flag{% endtrans %}</th>
|
<th>{% trans %}Flag{% endtrans %}</th>
|
||||||
|
Loading…
Reference in New Issue
Block a user