On ∞chan, you can create your own imageboard for free with no experience or programming knowledge needed. As long as the admin logs in once per week and it gets one new post every 72 hours, the board will be hosted forever.
- -- - - -
From 179df591af5aa97652ca5d204edf90e934db2ce7 Mon Sep 17 00:00:00 2001
From: 8chan ';
+}
+
+if (!$cbRecaptcha){
+ $recapcha_html = '';
+} else {
+ $recapcha_html = 'Game ' . $ayah->getPublisherHTML() . ' ';
+}
+
+
$password = base64_encode(openssl_random_pseudo_bytes(9));
$body = <<reCaptcha ' . recaptcha_get_html($config['recaptcha_public']) . ' Subtitle (must be < 200 chars)
Username (must contain only alphanumeric, periods and underscores)
-Password (write this down)
+{$game_html}
+{$recapcha_html}
Game {$publisher_html}
@@ -38,8 +59,27 @@ $title = $_POST['title'];
$subtitle = $_POST['subtitle'];
$username = $_POST['username'];
$password = $_POST['password'];
-$score = $ayah->scoreResult();
+ $resp = ($cbRecaptcha) ? recaptcha_check_answer ($config['recaptcha_private'],
+ $_SERVER["REMOTE_ADDR"],
+ $_POST["recaptcha_challenge_field"],
+ $_POST["recaptcha_response_field"]):false;
+
+if ($resp != false){
+$passedCaptcha = $resp->is_valid;
+} else {
+$passedCaptcha = true;
+}
+
+if (!$ayah){
+$score = true;
+} else {
+$score = $ayah->scoreResult();
+}
+if (!$score)
+ error('You failed the game');
+if (!$passedCaptcha)
+ error('You failed to enter the reCaptcha correctly');
if (!preg_match('/^[a-z0-9]{1,10}$/', $uri))
error('Invalid URI');
if (!(strlen($title) < 40))
@@ -48,8 +88,7 @@ if (!(strlen($subtitle) < 200))
error('Invalid subtitle');
if (!preg_match('/^[a-zA-Z0-9._]{1,30}$/', $username))
error('Invalid username');
-if (!$score)
- error('You failed the game');
+
foreach (listBoards() as $i => $board) {
if ($board['uri'] == $uri)
error('Board already exists!');
@@ -64,12 +103,13 @@ foreach ($bannedWords as $i => $w) {
error("Cannot create board matching banned pattern $w");
}
}
-$query = prepare('SELECT * FROM ``mods``');
+$query = prepare('SELECT ``username`` FROM ``mods`` WHERE ``username`` = :username');
+$query->bindValue(':username', $username);
$query->execute() or error(db_error($query));
$users = $query->fetchAll(PDO::FETCH_ASSOC);
-foreach ($users as $i => $user) {
- if ($user['username'] == $username)
- error('Username taken!');
+
+if (sizeof($users) > 0){
+error('The username you\'ve tried to enter already exists!');
}
$salt = generate_salt();
@@ -112,9 +152,10 @@ $body = <<
You can manage your site at http://8chan.co/mod.php?/.
+You can manage your board at http://8chan.co/mod.php?/.
EOT; echo Element("page.html", array("config" => $config, "body" => $body, "title" => "Success", "subtitle" => "This was a triumph")); } +?> diff --git a/expire.php b/expire.php index 8e822852..17356ac4 100644 --- a/expire.php +++ b/expire.php @@ -130,6 +130,10 @@ foreach($delete as $i => $d){ // Delete entire board directory rrmdir($board['uri'] . '/'); rrmdir('static/banners/' . $board['uri']); + // HAAAAAX + if($config['dir']['img_root'] != '') + rrmdir($config['dir']['img_root'] . $board['uri']); + cache::delete('board_' . $board['uri']); _syslog(LOG_NOTICE, "Board deleted: {$board['uri']}"); diff --git a/inc/api.php b/inc/api.php index a8ae9eed..a140cd7e 100644 --- a/inc/api.php +++ b/inc/api.php @@ -41,8 +41,8 @@ class Api { ); $this->fileFields = array( - 'thumbheight' => 'tn_w', - 'thumbwidth' => 'tn_h', + 'thumbheight' => 'tn_h', + 'thumbwidth' => 'tn_w', 'height' => 'w', 'width' => 'h', 'size' => 'fsize', @@ -113,6 +113,7 @@ class Api { $apiPost['ext'] = substr($file->file, $dotPos); $dotPos = strrpos($file->file, '.'); $apiPost['tim'] = substr($file->file, 0, $dotPos); + //$apiPost['md5'] = base64_encode(md5_file($file->file_path, true)); } return $apiPost; diff --git a/inc/config.php b/inc/config.php index e88f4935..3905f198 100644 --- a/inc/config.php +++ b/inc/config.php @@ -277,8 +277,21 @@ 'no_country' ); + + + /* Uses are you a human to stop automated requests to make boards disabled by default + * if you wish to use 'are you a human' to block automated board creation requests + + * to use AYAH you must enter your 'AYAH_PUBLISHER_KEY' and your 'AYAH_SCORING_KEY' in + * the configuration file for AYAH. The config file for AYAH + * is located in the following directory:'/inc/lib/ayah/ayah_config.php' + */ + $config['ayah_enabled'] = false; + // Enable reCaptcha to make spam even harder. Rarely necessary. $config['recaptcha'] = false; + // Enable reCaptcha on create.php to prevent automated requests. + $config['cbRecaptcha'] = false; // Public and private key pair from https://www.google.com/recaptcha/admin/create $config['recaptcha_public'] = '6LcXTcUSAAAAAKBxyFWIt2SO8jwx4W7wcSMRoN3f'; @@ -1119,6 +1132,12 @@ $config['dir']['thumb'] = 'thumb/'; $config['dir']['res'] = 'res/'; + // Images in a seperate directory - For CDN or media servers + // This is a particularly advanced feature - contact ctrlcctrlv or rails unless you + // really know what you're doing + $config['dir']['img_root'] = ''; + + // For load balancing, having a seperate server (and domain/subdomain) for serving static content is // possible. This can either be a directory or a URL. Defaults to $config['root'] . 'static/'. // $config['dir']['static'] = 'http://static.example.org/'; diff --git a/inc/functions.php b/inc/functions.php index 72c2e974..e127a87d 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -425,12 +425,12 @@ function setupBoard($array) { if (!file_exists($board['dir'])) @mkdir($board['dir'], 0777) or error("Couldn't create " . $board['dir'] . ". Check permissions.", true); - if (!file_exists($board['dir'] . $config['dir']['img'])) - @mkdir($board['dir'] . $config['dir']['img'], 0777) - or error("Couldn't create " . $board['dir'] . $config['dir']['img'] . ". Check permissions.", true); - if (!file_exists($board['dir'] . $config['dir']['thumb'])) - @mkdir($board['dir'] . $config['dir']['thumb'], 0777) - or error("Couldn't create " . $board['dir'] . $config['dir']['img'] . ". Check permissions.", true); + if (!file_exists($config['dir']['img_root'] . $board['dir'] . $config['dir']['img'])) + @mkdir($config['dir']['img_root'] . $board['dir'] . $config['dir']['img'], 0777) + or error("Couldn't create " . $config['dir']['img_root'] . $board['dir'] . $config['dir']['img'] . ". Check permissions.", true); + if (!file_exists($config['dir']['img_root'] . $board['dir'] . $config['dir']['thumb'])) + @mkdir($config['dir']['img_root'] . $board['dir'] . $config['dir']['thumb'], 0777) + or error("Couldn't create " . $config['dir']['img_root'] . $board['dir'] . $config['dir']['img'] . ". Check permissions.", true); if (!file_exists($board['dir'] . $config['dir']['res'])) @mkdir($board['dir'] . $config['dir']['res'], 0777) or error("Couldn't create " . $board['dir'] . $config['dir']['img'] . ". Check permissions.", true); @@ -997,11 +997,11 @@ function deleteFile($id, $remove_entirely_if_already=true, $file=null) { foreach ($files as $i => $f) { if (($file !== false && $i == $file) || $file === null) { // Delete thumbnail - file_unlink($board['dir'] . $config['dir']['thumb'] . $f->thumb); + file_unlink($config['dir']['img_root'] . $board['dir'] . $config['dir']['thumb'] . $f->thumb); unset($files[$i]->thumb); // Delete file - file_unlink($board['dir'] . $config['dir']['img'] . $f->file); + file_unlink($config['dir']['img_root'] . $board['dir'] . $config['dir']['img'] . $f->file); $files[$i]->file = 'deleted'; } } @@ -1080,8 +1080,8 @@ function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) { // Delete file foreach (json_decode($post['files']) as $i => $f) { if ($f->file !== 'deleted') { - file_unlink($board['dir'] . $config['dir']['img'] . $f->file); - file_unlink($board['dir'] . $config['dir']['thumb'] . $f->thumb); + file_unlink($config['dir']['img_root'] . $board['dir'] . $config['dir']['img'] . $f->file); + file_unlink($config['dir']['img_root'] . $board['dir'] . $config['dir']['thumb'] . $f->thumb); } } } diff --git a/inc/instance-config.php b/inc/instance-config.php index 96cc3c1c..5d7f7823 100644 --- a/inc/instance-config.php +++ b/inc/instance-config.php @@ -41,6 +41,7 @@ $config['allow_no_country'] = true; $config['thread_subject_in_title'] = true; $config['spam']['hidden_inputs_max_pass'] = 128; + $config['ayah_enabled'] = true; include "secrets.php"; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index f7ccf1a6..21e7c248 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -429,6 +429,9 @@ function mod_edit_board($boardName) { // Delete entire board directory rrmdir($board['uri'] . '/'); + // To reiterate: HAAAAAX + if($config['dir']['img_root'] != '') + rrmdir($config['dir']['img_root'] . $board['uri']); } else { $query = prepare('UPDATE ``boards`` SET `title` = :title, `subtitle` = :subtitle WHERE `uri` = :uri'); $query->bindValue(':uri', $board['uri']); @@ -1121,8 +1124,8 @@ function mod_move_reply($originBoard, $postID) { $post['files'] = json_decode($post['files'], TRUE); $post['has_file'] = true; foreach ($post['files'] as $i => &$file) { - $file['file_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']; - $file['thumb_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']; + $file['file_path'] = sprintf($config['board_path'], $config['dir']['img_root'] . $board['uri']) . $config['dir']['img'] . $file['file']; + $file['thumb_path'] = sprintf($config['board_path'], $config['dir']['img_root'] . $board['uri']) . $config['dir']['thumb'] . $file['thumb']; } } else { $post['has_file'] = false; @@ -1140,9 +1143,9 @@ function mod_move_reply($originBoard, $postID) { if ($post['has_file']) { foreach ($post['files'] as $i => &$file) { // move the image - rename($file['file_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']); + rename($file['file_path'], sprintf($config['board_path'], $config['dir']['img_root'] . $board['uri']) . $config['dir']['img'] . $file['file']); if ($file['thumb'] != 'spoiler') { //trying to move/copy the spoiler thumb raises an error - rename($file['thumb_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']); + rename($file['thumb_path'], sprintf($config['board_path'], $config['dir']['img_root'] . $board['uri']) . $config['dir']['thumb'] . $file['thumb']); } } } @@ -1222,8 +1225,8 @@ function mod_move($originBoard, $postID) { foreach ($post['files'] as $i => &$file) { if ($file['file'] === 'deleted') continue; - $file['file_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']; - $file['thumb_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']; + $file['file_path'] = sprintf($config['board_path'], $config['dir']['img_root'] . $board['uri']) . $config['dir']['img'] . $file['file']; + $file['thumb_path'] = sprintf($config['board_path'], $config['dir']['img_root'] . $board['uri']) . $config['dir']['thumb'] . $file['thumb']; } } else { $post['has_file'] = false; @@ -1242,9 +1245,9 @@ function mod_move($originBoard, $postID) { // copy image foreach ($post['files'] as $i => &$file) { if ($file['file'] !== 'deleted') - $clone($file['file_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']); + $clone($file['file_path'], sprintf($config['board_path'], $config['dir']['img_root'] . $board['uri']) . $config['dir']['img'] . $file['file']); if (isset($file['thumb']) && !in_array($file['thumb'], array('spoiler', 'deleted', 'file'))) - $clone($file['thumb_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']); + $clone($file['thumb_path'], sprintf($config['board_path'], $config['dir']['img_root'] . $board['uri']) . $config['dir']['thumb'] . $file['thumb']); } } @@ -1265,8 +1268,8 @@ function mod_move($originBoard, $postID) { $post['files'] = json_decode($post['files'], TRUE); $post['has_file'] = true; foreach ($post['files'] as $i => &$file) { - $file['file_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']; - $file['thumb_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']; + $file['file_path'] = sprintf($config['board_path'], $config['dir']['img_root'] . $board['uri']) . $config['dir']['img'] . $file['file']; + $file['thumb_path'] = sprintf($config['board_path'], $config['dir']['img_root'] . $board['uri']) . $config['dir']['thumb'] . $file['thumb']; } } else { $post['has_file'] = false; @@ -1305,8 +1308,8 @@ function mod_move($originBoard, $postID) { if ($post['has_file']) { // copy image foreach ($post['files'] as $i => &$file) { - $clone($file['file_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']); - $clone($file['thumb_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']); + $clone($file['file_path'], sprintf($config['board_path'], $config['dir']['img_root'] . $board['uri']) . $config['dir']['img'] . $file['file']); + $clone($file['thumb_path'], sprintf($config['board_path'], $config['dir']['img_root'] . $board['uri']) . $config['dir']['thumb'] . $file['thumb']); } } // insert reply @@ -1582,7 +1585,7 @@ function mod_spoiler_image($board, $post, $file) { $result = $query->fetch(PDO::FETCH_ASSOC); $files = json_decode($result['files']); - file_unlink($board . '/' . $config['dir']['thumb'] . $files[$file]->thumb); + file_unlink($config['dir']['img_root'] . $board . '/' . $config['dir']['thumb'] . $files[$file]->thumb); $files[$file]->thumb = 'spoiler'; $files[$file]->thumbheight = 128; $files[$file]->thumbwidth = 128; @@ -1799,12 +1802,25 @@ function mod_user($uid) { $log = array(); } + if ($mod['type'] >= ADMIN){ + $boards = listBoards(); + } else { + $boards2 = explode(',', $user['boards']); + + foreach($boards2 as $string){ + + $boards[] = array("uri"=>$string, "title"=>"MY BOARD"); + + } + + + } $user['boards'] = explode(',', $user['boards']); mod_page(_('Edit user'), 'mod/user.html', array( 'user' => $user, 'logs' => $log, - 'boards' => listBoards(), + 'boards' => $boards, 'token' => make_secure_link_token('users/' . $user['id']) )); } diff --git a/install.sql b/install.sql index 969107a2..b8d95444 100644 --- a/install.sql +++ b/install.sql @@ -68,6 +68,11 @@ CREATE TABLE IF NOT EXISTS `boards` ( PRIMARY KEY (`uri`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; +CREATE TABLE IF NOT EXISTS `board_create` ( + `time` text NOT NULL, + `uri` text NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + -- -- Dumping data for table `boards` -- @@ -220,6 +225,7 @@ CREATE TABLE IF NOT EXISTS `reports` ( `board` varchar(58) CHARACTER SET utf8 DEFAULT NULL, `post` int(11) NOT NULL, `reason` text NOT NULL, + `global` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ; diff --git a/js/auto-reload.js b/js/auto-reload.js index 535b9a04..583a43e8 100644 --- a/js/auto-reload.js +++ b/js/auto-reload.js @@ -16,8 +16,16 @@ * */ + +au = false; auto_reload_enabled = true; // for watch.js to interop +function makeIcon(){ + if(au) return; + au = true; + $("link[rel='icon']").attr("href", "../static/favicon_au.png"); +} + $(document).ready(function(){ if($('div.banner').length == 0) return; // not index @@ -98,6 +106,7 @@ $(document).ready(function(){ if($('#' + id).length == 0) { if (!new_posts) { first_new_post = this; + makeIcon(); } $(this).insertAfter($('div.post:last').next()).after('L | Board | Board title | Posts in last hour | Total posts | Created |
---|---|---|---|---|---|
$img | "; - $body .= "/{$board['uri']}/$lock | "; - $body .= "{$board['title']} | "; - $body .= "{$board['pph']} | "; - $body .= "{$board['max']} | "; - $body .= "{$board['time']} ({$board['ago']} ago) |
There are currently {$n_boards} boards + $hidden_boards_total unindexed boards = $t_boards total boards. Site-wide, {$total_posts_hour} posts have been made in the last hour, with {$total_posts} being made on all active boards since October 23, 2013.
" . $body; - -//date_default_timezone_set('UTC'); -$body .= "Page last updated: ".date('r')."
"; -$body .= "".shell_exec('uptime -p')." without interruption
"; - $config['additional_javascript'] = array('js/jquery.min.js', 'js/jquery.tablesorter.min.js'); +$body = Element("8chan/boards.html", array("config" => $config, "n_boards" => $n_boards, "t_boards" => $t_boards, "hidden_boards_total" => $hidden_boards_total, "total_posts" => $total_posts, "total_posts_hour" => $total_posts_hour, "boards" => $boards, "last_update" => date('r'), "uptime_p" => shell_exec('uptime -p'))); + $html = Element("page.html", array("config" => $config, "body" => $body, "title" => "Boards on ∞chan")); if ($admin) { echo $html; diff --git a/create.php b/create.php index 41efa666..88f3952e 100644 --- a/create.php +++ b/create.php @@ -20,7 +20,7 @@ if (!isset($_POST['uri'], $_POST['title'], $_POST['subtitle'], $_POST['username' if (!$ayah){ $game_html = ''; } else { - $game_html = 'URI | // (must be all lowercase or numbers and < 10 chars) |
---|---|
Title | (must be < 40 chars) |
Subtitle | (must be < 200 chars) |
Username | (must contain only alphanumeric, periods and underscores) |
Password | (write this down) |
Your new board is created and is live at /{$uri}/.
- -Make sure you don't forget your password, {$_POST['password']}!
- -You can manage your board at http://8chan.co/mod.php?/.
- -EOT; - -echo Element("page.html", array("config" => $config, "body" => $body, "title" => "Success", "subtitle" => "This was a triumph")); +echo Element("page.html", array("config" => $config, "body" => $body, "title" => _("Success"), "subtitle" => _("This was a triumph"))); } ?> diff --git a/index.php b/index.php index 83a6451b..1aa350c6 100644 --- a/index.php +++ b/index.php @@ -1,323 +1,4 @@ +include 'inc/functions.php'; - - - - -On ∞chan, you can create your own imageboard for free with no experience or programming knowledge needed. As long as the admin logs in once per week and it gets one new post every 72 hours, the board will be hosted forever.
- -{% trans %}There are currently {{n_boards}} boards + {{hidden_boards_total}} unindexed boards = {{t_boards}} total boards. Site-wide, {{total_posts_hour}} posts have been made in the last hour, with {{total_posts}} being made on all active boards since October 23, 2013.{% endtrans %}
+ +L | {% trans %}Board{% endtrans %} | {% trans %}Board title{% endtrans %} | {% trans %}Posts in last hour{% endtrans %} | {% trans %}Total posts{% endtrans %} | {% trans %}Created{% endtrans %} |
---|---|---|---|---|---|
{{ board.img|raw }} | +/{{board['uri']}}/{{lock|raw}} | +{{ board['title'] }} | +{{board['pph']}} | +{{board['max']}} | +{{board['time']}} ({{board['ago']}} ago) |
Page last updated: {{last_update}}
+{{uptime_p}} without interruption
+ + diff --git a/templates/8chan/create.html b/templates/8chan/create.html new file mode 100644 index 00000000..668d165a --- /dev/null +++ b/templates/8chan/create.html @@ -0,0 +1,15 @@ + + diff --git a/templates/8chan/create_success.html b/templates/8chan/create_success.html new file mode 100644 index 00000000..b129787c --- /dev/null +++ b/templates/8chan/create_success.html @@ -0,0 +1,5 @@ +{% trans %}Your new board is created and is live at{% endtrans %} /{{ uri }}/.
+ +{% trans %}Make sure you don't forget your password, {{ password }}!{% endtrans %}
+ +{% trans %}You can manage your board at http://8chan.co/mod.php?/.{% endtrans %}
diff --git a/templates/8chan/index.html b/templates/8chan/index.html new file mode 100644 index 00000000..54ceae28 --- /dev/null +++ b/templates/8chan/index.html @@ -0,0 +1,311 @@ + + + + +{% trans %}On ∞chan, you can create your own imageboard for free with no experience or programming knowledge needed. As long as the admin logs in once per week and it gets one new post every 72 hours, the board will be hosted forever.{% endtrans %}
+ +