1349 lines
47 KiB
PHP
1349 lines
47 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This is the endboard software, version beta 0.73
|
|
* It is a textboard written for the use in the darknets.
|
|
*
|
|
* This file holds all the functions for admins and mods. It can be
|
|
* included without side effects.
|
|
*
|
|
* The writing of this code started some time ago with another software
|
|
* called smolBBS. Although there is almost no original code left now,
|
|
* I still regard endboard as a fork of smolBBS.
|
|
* The author of smolBBS has required that the following text be
|
|
* distributed with any redistribution, so here it goes.
|
|
* The license and other conditions apply to endboard as well.
|
|
*
|
|
* IRC: *dulm @ irc.rizon.net
|
|
*
|
|
* Copyright (C) 2020 sandlind
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* (1) Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* (2) Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
*
|
|
* (3)The name of the author may not be used to
|
|
* endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
// Lets the admin change the status of a mod or an applicant
|
|
function change_mods($db, $css, $settings, $token)
|
|
{
|
|
|
|
if ( (isset($_POST['disable_mod'])) ) {
|
|
$mod = strip_tags($_POST['disable_mod']);
|
|
$statement = $db->prepare("UPDATE keys
|
|
SET type = 'disabled'
|
|
WHERE name = '$mod'");
|
|
$log_message = "Moderator account $mod was disabled";
|
|
} elseif ( (isset($_POST['enable_mod'])) ) {
|
|
$mod = strip_tags($_POST['enable_mod']);
|
|
$statement = $db->prepare("UPDATE keys
|
|
SET type = 'mod'
|
|
WHERE name = '$mod'");
|
|
$log_message = "Moderator account $mod was enabled";
|
|
} elseif ( (isset($_POST['delete_mod'])) ) {
|
|
$mod = strip_tags($_POST['delete_mod']);
|
|
$statement = $db->prepare("DELETE FROM keys
|
|
WHERE name = '$mod'");
|
|
$log_message = "Moderator account $mod was deleted";
|
|
}
|
|
|
|
$result = $statement->execute();
|
|
|
|
log_event($db, $settings, "sys", $log_message, '');
|
|
|
|
}
|
|
|
|
// Check if the password for the admin is set or not.
|
|
// If it was not done already, generate token and write to db and the
|
|
// file /var/opt/endboard/admin_$name_token.txt
|
|
function check_admin($db, $settings)
|
|
{
|
|
|
|
if ( ($settings['admin'] == 'change-me')
|
|
|| ($settings['admin'] == '') ) {
|
|
$config_file = $settings['config_file'];
|
|
$admin_message = "<h1>The name of the admin is not updated "
|
|
. "in the configfile, or it is empty. Set "
|
|
. "the variable \$admin in the file "
|
|
. " $config_file and retry.</h1>";
|
|
quit($db, $admin_message);
|
|
}
|
|
|
|
$admin = $settings['admin'];
|
|
$filename = $settings['work_dir'] . 'admin_' . $admin . '_token.txt';
|
|
|
|
$statement = $db->prepare("SELECT key FROM keys
|
|
WHERE type = 'admin'
|
|
AND name = '$admin'");
|
|
$result = $statement->execute();
|
|
|
|
$key = '';
|
|
$counter = 0;
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$key = "{$row[0]}";
|
|
$counter++;
|
|
}
|
|
|
|
if ( ($key == '') && (!file_exists($filename)) ) {
|
|
$token = make_token(250, 'alnum');
|
|
$token_hash = password_hash($token, PASSWORD_DEFAULT);
|
|
|
|
if ($counter == 0) {
|
|
$statement = $db->prepare("INSERT INTO keys(token, type, name)
|
|
VALUES ('$token_hash',
|
|
'admin',
|
|
'$admin')");
|
|
} else {
|
|
$statement = $db->prepare("UPDATE keys
|
|
SET token = '$token_hash'
|
|
WHERE name = '$admin'
|
|
AND type = 'admin'");
|
|
}
|
|
|
|
$result = $statement->execute();
|
|
|
|
$content = "Token = \r\n$token\r\n";
|
|
file_put_contents($filename, $content);
|
|
|
|
return FALSE;
|
|
} elseif ( ($key == '') ) {
|
|
return FALSE;
|
|
} else {
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
// Check if access to the admin panel is enabled in the config file.
|
|
function check_admin_panel($db, $settings)
|
|
{
|
|
|
|
if ($settings['enable_admin_panel'] != TRUE) {
|
|
header( 'HTTP/1.1 403 Forbidden' );
|
|
quit($db, '403');
|
|
}
|
|
|
|
}
|
|
|
|
// Checks if the number of moderators applications is more than 10.
|
|
function check_application_count($db)
|
|
{
|
|
|
|
$statement = $db->prepare("SELECT name
|
|
FROM keys
|
|
WHERE type = 'application'");
|
|
$result = $statement->execute();
|
|
|
|
$counter = 0;
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$counter++;
|
|
}
|
|
|
|
if ($counter > 10) {
|
|
// 10 seems reasonable in order not to loose the overview
|
|
return FALSE;
|
|
} else {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
// Check if access to the admin panel and its functions can be given
|
|
// or not. First, the token is checked, if there
|
|
// is one. If there is none, user/password is checked against the db.
|
|
// If the login is successful, a token is created and given back.
|
|
function check_auth_admin($db, $settings)
|
|
{
|
|
|
|
$token = read_pretty_vars('last', 'alnum', 250);
|
|
// The length of the token is 250 characters
|
|
|
|
if ( (mb_strlen($token) !== 250) ) {
|
|
// The length of the token is 250 characters
|
|
$token = get_post_token();
|
|
}
|
|
|
|
if ( (mb_strlen($token) === 250) ) {
|
|
// The length of the token is 250 characters
|
|
$statement = $db->prepare("SELECT timestamp_token, token, name
|
|
FROM keys
|
|
WHERE type = 'admin'");
|
|
$result = $statement->execute();
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$timestamp_token = "{$row[0]}";
|
|
$access_token = "{$row[1]}";
|
|
$auth_name = "{$row[2]}";
|
|
}
|
|
|
|
$current = time();
|
|
$max_age = $current - ($settings['lifetime_token'] * 60);
|
|
// max lifetime is defined in minutes, times 60 to go to seconds
|
|
|
|
if ( ($timestamp_token < $max_age) ) {
|
|
$auth_message = 'outdated token used';
|
|
log_event($db, $settings, 'auth', $auth_message, '');
|
|
$quit_message = '<h1>Token expired.<a href=\'/aa\'>Log in </a>'
|
|
. 'again to get a new one.'
|
|
. 'This incident was logged.</h1>';
|
|
quit($db, $quit_message);
|
|
}
|
|
|
|
if ( (!password_verify($token, $access_token)) ) {
|
|
$auth_message = 'invalid token used';
|
|
log_event($db, $settings, 'auth', $auth_message, '');
|
|
sleep(10);
|
|
$quit_message = '<h1>Invalid token used.'
|
|
. 'This incident was logged.</h1>';
|
|
quit($db, $quit_message);
|
|
}
|
|
|
|
} elseif ( (!isset($_POST['auth_name']))
|
|
|| (!isset($_POST['auth_password'])) ) {
|
|
$quit_message = '<h1>Please provide the name and'
|
|
. ' password for your account.</h1>';
|
|
quit($db, $quit_message);
|
|
} else {
|
|
$auth_name = filter($_POST['auth_name'], 'alnum', 50);
|
|
// 50 seems to be a generous for the length of the username
|
|
$statement = $db->prepare("SELECT key
|
|
FROM keys
|
|
WHERE type = 'admin'
|
|
AND name = '$auth_name'");
|
|
$result = $statement->execute();
|
|
|
|
$key = '';
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$key = "{$row[0]}";
|
|
}
|
|
|
|
if ( (!password_verify($_POST['auth_password'], $key)) ) {
|
|
$auth_message = 'wrong combination user/password';
|
|
log_event($db, $settings, 'auth', $auth_message, '');
|
|
sleep(10);
|
|
$quit_message = '<h1>Combination of password and username '
|
|
. 'is invalid. This incident was logged.</h1>';
|
|
quit($db, $quit_message);
|
|
}
|
|
|
|
$auth_message = "admin $auth_name logged on";
|
|
log_event($db, $settings, 'auth', $auth_message, '');
|
|
|
|
$current = time();
|
|
|
|
$statement = $db->prepare("UPDATE keys
|
|
SET timestamp_token = '$current'
|
|
WHERE name = '$auth_name'
|
|
AND type = 'admin'");
|
|
$result = $statement->execute();
|
|
|
|
}
|
|
|
|
$token = make_token(250, 'alnum');
|
|
$token_hash = password_hash($token, PASSWORD_DEFAULT);
|
|
|
|
$statement = $db->prepare("UPDATE keys
|
|
SET token = '$token_hash'
|
|
WHERE name = '$auth_name'
|
|
AND type = 'admin'");
|
|
$result = $statement->execute();
|
|
|
|
return $token;
|
|
}
|
|
|
|
// Check if access to the mod panel and can be given or not.
|
|
// The token is checked, if there is one. If there is none,
|
|
// user/password is checked against the db.
|
|
// If the login is successful, a token is created and given back.
|
|
function check_auth_mod($db, $settings)
|
|
{
|
|
|
|
$token = read_pretty_vars('last', 'alnum', 250);
|
|
// the length of the token is defined to 250 characters, so that it
|
|
// cannot be memorized,
|
|
// and so that it does never show fully in the addressbar
|
|
|
|
if ( (mb_strlen($token) !== 250) ) {
|
|
// token length = 250
|
|
$token = get_post_token();
|
|
}
|
|
|
|
if ( (mb_strlen($token) === 250) ) {
|
|
// token length = 250
|
|
$statement = $db->prepare("SELECT timestamp_token, token, name
|
|
FROM keys
|
|
WHERE type = 'mod'");
|
|
$result = $statement->execute();
|
|
|
|
$found_token = FALSE;
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$timestamp_token = "{$row[0]}";
|
|
$access_token = "{$row[1]}";
|
|
$auth_name = "{$row[2]}";
|
|
if ( (password_verify($token, $access_token)) ) {
|
|
$found_token = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( ($found_token == FALSE) ) {
|
|
$auth_message = 'invalid token used';
|
|
log_event($db, $settings, 'auth', $auth_message, '');
|
|
quit($db, '<h1>Token invalid. This incident was logged.</h1>');
|
|
}
|
|
|
|
$current = time();
|
|
$max_age = $current - ($settings['lifetime_token'] * 60);
|
|
// lifetime of token is in minutes, times 60 to go to seconds
|
|
|
|
if ($timestamp_token < $max_age) {
|
|
$auth_message = 'outdated token used';
|
|
log_event($db, $settings, 'auth', $auth_message, '');
|
|
$quit_message = '<h1>Token expired.<a href=\'/am\'>Log in</a>'
|
|
. ' again to get a new one. '
|
|
. 'This incident was logged.</h1>';
|
|
quit($db, $quit_message);
|
|
}
|
|
} elseif ( (!isset($_POST['auth_name']))
|
|
|| (!isset($_POST['auth_password'])) ) {
|
|
$quit_message = '<h1>Please provide the name'
|
|
. ' and password for your account.</h1>';
|
|
quit($db, $quit_message);
|
|
} else {
|
|
$auth_name = filter($_POST['auth_name'], 'alnum', 50);
|
|
// 50 seems to be a generous for the length of the username
|
|
$statement = $db->prepare("SELECT key FROM keys
|
|
WHERE type = 'mod'
|
|
AND name = '$auth_name'");
|
|
$result = $statement->execute();
|
|
|
|
$key = '';
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$key = "{$row[0]}";
|
|
}
|
|
|
|
if ( (!password_verify($_POST['auth_password'], $key)) ) {
|
|
$auth_message = 'wrong combination user/password';
|
|
log_event($db, $settings, 'auth', $auth_message, '');
|
|
sleep(10);
|
|
$quit_message = '<h1>Combination of password and username is'
|
|
. ' invalid. This incident was logged.</h1>';
|
|
quit($db, $quit_message);
|
|
}
|
|
|
|
$auth_message = "mod $auth_name logged on";
|
|
log_event($db, $settings, 'auth', $auth_message, '');
|
|
|
|
$current = time();
|
|
|
|
$statement = $db->prepare("UPDATE keys
|
|
SET timestamp_token = '$current'
|
|
WHERE name = '$auth_name'
|
|
AND type = 'mod'");
|
|
$result = $statement->execute();
|
|
|
|
}
|
|
|
|
$token = make_token(250, 'alnum');
|
|
$token_hash = password_hash($token, PASSWORD_DEFAULT);
|
|
|
|
$statement = $db->prepare("UPDATE keys
|
|
SET token = '$token_hash'
|
|
WHERE name = '$auth_name'
|
|
AND type = 'mod'");
|
|
$result = $statement->execute();
|
|
|
|
return $token;
|
|
}
|
|
|
|
// Check if access to the mod panel is enabled in the config file.
|
|
function check_mod_panel($db, $settings)
|
|
{
|
|
|
|
if ($settings['enable_mod_panel'] != TRUE) {
|
|
header( 'HTTP/1.1 403 Forbidden' );
|
|
quit($db, '403');
|
|
}
|
|
|
|
}
|
|
|
|
// Delete selected logs
|
|
function delete_logs($db, $type, $token)
|
|
{
|
|
|
|
if ($type == 'all') {
|
|
$statement = $db->prepare("DELETE FROM logs");
|
|
$delete_message = 'all logs were deleted';
|
|
} else {
|
|
$statement = $db->prepare("DELETE FROM logs
|
|
WHERE type = '$type'");
|
|
$delete_message = "logs of type $type were deleted";
|
|
}
|
|
|
|
$result = $statement->execute();
|
|
|
|
echo "$delete_message";
|
|
}
|
|
|
|
// Delete one post or a range of posts.
|
|
// If you use php8.* you can change to str_contains below.
|
|
function delete_posts($db, $sub, $settings, $token, $delete_mode)
|
|
{
|
|
//rewrite to check if post exists first,
|
|
// and only move it if it is not shadowed
|
|
if ($delete_mode == 'shadow') {
|
|
$posts = strip_tags($_POST['shadow_posts']);
|
|
} elseif ($delete_mode == 'move') {
|
|
$posts = strip_tags($_POST['shadow_posts']);
|
|
$target_sub = filter($_POST['target_sub'], 'alnum',
|
|
$settings['max_name_sub']);
|
|
if ( (check_sub_exists($db, $target_sub) != TRUE) ) {
|
|
quit($db, "<h1>Sub $target_sub does not exist.</h1>");
|
|
}
|
|
} else {
|
|
$posts = strip_tags($_POST['delete_posts']);
|
|
}
|
|
|
|
// if (str_contains($posts, '-')) {
|
|
// only uncomment if you use php8.*
|
|
if (strpos($posts, '-') !== FALSE) {
|
|
$delete_minmax = explode('-', $posts);
|
|
$delete_array = array();
|
|
for($delete = $delete_minmax['0'];
|
|
$delete <= $delete_minmax['1']; $delete++) {
|
|
array_push($delete_array, $delete);
|
|
}
|
|
} else {
|
|
$delete_array = explode(' ', $posts);
|
|
}
|
|
|
|
$statement = $db->prepare("SELECT name, token
|
|
FROM keys
|
|
WHERE type = 'mod'");
|
|
$result = $statement->execute();
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$name = "{$row[0]}";
|
|
$access_token = "{$row[1]}";
|
|
if ( (password_verify($token, $access_token)) ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
$html_string = '';
|
|
|
|
if ( (!empty($delete_array)) && ($delete_mode == 'delete') ) {
|
|
|
|
foreach($delete_array as $delete_post) {
|
|
$statement = $db->prepare("DELETE FROM threads
|
|
WHERE post_id = '$delete_post'
|
|
AND sub = '$sub'");
|
|
$result = $statement->execute();
|
|
|
|
$delete_message = "message $delete_post from "
|
|
. "sub $sub deleted by $name";
|
|
log_event($db, $settings, "del", $delete_message, '');
|
|
$html_string .= "<h1>$delete_message</h1>";
|
|
|
|
}
|
|
|
|
} elseif ( (!empty($delete_array)) && ($delete_mode == 'shadow') ) {
|
|
|
|
foreach($delete_array as $delete_post) {
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET shadow = 'yes'
|
|
WHERE post_id = '$delete_post'
|
|
AND sub = '$sub'");
|
|
$result = $statement->execute();
|
|
|
|
$delete_message = "message $delete_post from ";
|
|
$delete_message .= "sub $sub shadowed by $name";
|
|
log_event($db, $settings, "del", $delete_message, '');
|
|
|
|
$html_string .= "<h1>$delete_message</h1>";
|
|
}
|
|
|
|
} elseif ( (!empty($delete_array)) && ($delete_mode == 'move') ) {
|
|
|
|
move_post($db, $settings, $delete_array, $sub, $target_sub, $name);
|
|
|
|
}
|
|
|
|
$html_string .= '<h1>Done.</h1>';
|
|
|
|
if ($delete_mode == 'delete') {
|
|
$html_string .= "<h1><a href='/a/$sub/8/$token'>Back</a></h1>";
|
|
} else {
|
|
$html_string .= "<h1><a href='/m/$sub/7/$token'>Back</a></h1>";
|
|
}
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
// Delete or shadow a whole sub
|
|
function delete_sub($db, $sub, $settings, $token, $shadow_only)
|
|
{
|
|
|
|
$token_hash = hash('sha512',$token);
|
|
$statement = $db->prepare("SELECT name
|
|
FROM keys
|
|
WHERE token = '$token_hash'");
|
|
$result = $statement->execute();
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$name = "{$row[0]}";
|
|
}
|
|
|
|
$html_string = '';
|
|
|
|
if ( ($sub != '') && ($shadow_only == 'no') ) {
|
|
|
|
$statement = $db->prepare("DELETE FROM threads
|
|
WHERE sub = '$sub'");
|
|
$result = $statement->execute();
|
|
|
|
$delete_message = "sub $sub deleted by $name";
|
|
log_event($db, $settings, "del", $delete_message, '');
|
|
|
|
$html_string .= "<h1>$delete_message</h1>";
|
|
|
|
} elseif ( ($sub != '') && ($shadow_only == 'yes') ) {
|
|
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET shadow = 'yes'
|
|
WHERE sub = '$sub'");
|
|
$result = $statement->execute();
|
|
|
|
$delete_message = "sub $sub shadowed by $name";
|
|
log_event($db, $settings, "del", $delete_message, '');
|
|
|
|
$html_string .= "<h1>$delete_message</h1>";
|
|
}
|
|
|
|
$html_string .= "<h1>Done.</h1>";
|
|
|
|
if ($shadow_only == 'yes') {
|
|
$html_string .= "<h1><a href='/m/main/7/$token'>Back</a></h1>";
|
|
} else {
|
|
$html_string .= "<h1><a href='/a/main/8/$token'>Back</a></h1>";
|
|
}
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
// Delete an admin or mod token to end the session
|
|
function destroy_token($db, $token, $settings, $log_message)
|
|
{
|
|
|
|
$name = '';
|
|
|
|
$statement = $db->prepare("SELECT name, token
|
|
FROM keys");
|
|
$result = $statement->execute();
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$name = "{$row[0]}";
|
|
$access_token = "{$row[1]}";
|
|
if ( (password_verify($token, $access_token)) ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( (empty($name)) ) {
|
|
$log_message = 'invalid token used';
|
|
} else {
|
|
$statement = $db->prepare("UPDATE keys
|
|
SET token = 'none'
|
|
WHERE name = '$name'");
|
|
$result = $statement->execute();
|
|
$log_message .= ": $name";
|
|
}
|
|
|
|
log_event($db, $settings, 'auth', $log_message, '');
|
|
}
|
|
|
|
// do a full dump of the board, including names and tripcodes. The file
|
|
// will be saved locally (in /var/opt/endboard/). Can be called by the
|
|
// admin via the admins interface, or from cli.
|
|
function dump_full($db, $settings)
|
|
{
|
|
// rewrite to include ranges
|
|
$json_dump = array();
|
|
|
|
$statement = $db->prepare("SELECT post_id, org_id,
|
|
sub, text, timestamp, name,
|
|
tripcode, original, shadow,
|
|
move_message, edit_message
|
|
FROM threads
|
|
");
|
|
$result = $statement->execute();
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$post = array();
|
|
$post['post_id'] = "{$row[0]}";
|
|
$post['org_id'] = "{$row[1]}";
|
|
$post['sub'] = "{$row[2]}";
|
|
$post['text'] = "{$row[3]}";
|
|
$post['timestamp'] = "{$row[4]}";
|
|
$post['name'] = "{$row[5]}";
|
|
$post['tripcode'] = "{$row[6]}";
|
|
$post['original'] = "{$row[7]}";
|
|
$post['shadow'] = "{$row[8]}";
|
|
$post['move_message'] = "{$row[9]}";
|
|
$post['edit_message'] = "{$row[10]}";
|
|
array_push($json_dump, $post);
|
|
}
|
|
|
|
$diff = make_token(20, 'alnum');
|
|
$filename = $settings['work_dir'] . 'full_dump_' . $diff . '.json';
|
|
|
|
file_put_contents($filename, json_encode($json_dump,
|
|
JSON_PRETTY_PRINT
|
|
| JSON_NUMERIC_CHECK
|
|
| JSON_UNESCAPED_UNICODE));
|
|
|
|
}
|
|
|
|
|
|
// This function can be used to replicate an existing board.
|
|
// Save the dump from the overboard of the existing board, then put
|
|
// it under /var/opt/endboard/board.json of your new server
|
|
// (or whatever name you defined in the config-file).
|
|
// Log in to your admin panel, click on link 'import' in the footer
|
|
function import_overboard($db, $settings)
|
|
{
|
|
|
|
$board_file = $settings['work_dir'] . $settings['import_file'];
|
|
|
|
if ( file_exists($board_file) ) {
|
|
$html_string = "<div class='post'>Found importfile $board_file </div>";
|
|
} else {
|
|
$html_string = "<div class='post'>Could not find importfile "
|
|
. "$board_file, aborting.</div>";
|
|
echo "$html_string";
|
|
return;
|
|
}
|
|
|
|
$board_json = file_get_contents($board_file);
|
|
$board_list = json_decode($board_json, TRUE);
|
|
$counter = 0;
|
|
|
|
foreach($board_list as $post) {
|
|
$post_id = $post['post_id'];
|
|
$text = $post['text'];
|
|
$sub = $post['sub'];
|
|
$org_id = $post['org_id'];
|
|
|
|
if (!empty($post['timestamp'])) {
|
|
$timestamp = $post['timestamp'];
|
|
} else {
|
|
$timestamp = '';
|
|
}
|
|
|
|
if (!empty($post['name'])) {
|
|
$name = $post['name'];
|
|
} else {
|
|
$name = '';
|
|
}
|
|
|
|
if (!empty($post['tripcode'])) {
|
|
$tripcode = $post['tripcode'];
|
|
} else {
|
|
$tripcode = '';
|
|
}
|
|
|
|
if (!empty($post['move_message'])) {
|
|
$move_message = $post['move_message'];
|
|
} else {
|
|
$move_message = '';
|
|
}
|
|
|
|
if (!empty($post['edit_message'])) {
|
|
$edit_message = $post['edit_message'];
|
|
} else {
|
|
$edit_message = '';
|
|
}
|
|
|
|
if ( (!empty($text)) && (!empty($sub))
|
|
&& (!empty($post_id)) && (!empty($org_id)) ) {
|
|
if (!check_post_exists($db, $sub, $post_id)) {
|
|
$global_id = hash('sha512', $sub . $post_id .
|
|
$org_id . $text . $timestamp);
|
|
$text_id = hash('sha512', $text);
|
|
|
|
$statement = $db->prepare("INSERT OR IGNORE INTO threads
|
|
(post_id, sub, text, org_id,
|
|
shadow, global_id, text_id,
|
|
timestamp, name, tripcode,
|
|
original, move_message,
|
|
edit_message)
|
|
VALUES ('$post_id', '$sub', ?,
|
|
'$org_id', 'no', '$global_id',
|
|
'$text_id', '$timestamp',
|
|
'$name', '$tripcode',
|
|
'$post_id', ?, ?')");
|
|
$statement->bindParam(1, $text);
|
|
$statement->bindParam(2, $move_message);
|
|
$statement->bindParam(3, $edit_message);
|
|
|
|
$statement->execute();
|
|
|
|
$counter++;
|
|
$import_message = "message $post_id from sub $sub imported";
|
|
log_event($db, $settings, 'import', $import_message, '');
|
|
$html_string .= "<div class='post'>$import_message</div>";
|
|
} else {
|
|
$import_message = "message $post_id from sub $sub"
|
|
. " existed already and was not imported";
|
|
log_event($db, $settings, 'import', $import_message, '');
|
|
$html_string .= "<div class='post'>$import_message</div>";
|
|
}
|
|
}
|
|
}
|
|
|
|
rename($board_file, $board_file . '.done');
|
|
|
|
$html_string .= "<div class='post'>Finished, imported "
|
|
. "$counter messages altogether.</div>"
|
|
. "<div class='post'>The boardfile was "
|
|
. "renamed to avoid another import.</div>";
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
// Moves a post to a different sub. In case it is an original post, all
|
|
// replies are moved as well.
|
|
function move_post($db, $settings, $delete_array, $sub, $target_sub, $name)
|
|
{
|
|
foreach($delete_array as $delete_post) {
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET shadow = 'yes'
|
|
WHERE post_id = '$delete_post'
|
|
AND sub = '$sub'");
|
|
$result = $statement->execute();
|
|
|
|
$statement = $db->prepare("SELECT post_id, org_id, text, name,
|
|
timestamp, tripcode, move_message,
|
|
edit_message, original
|
|
FROM threads
|
|
WHERE post_id = '$delete_post'
|
|
AND sub = '$sub'");
|
|
$result = $statement->execute();
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$post_id = "{$row[0]}";
|
|
$org_id = "{$row[1]}";
|
|
$text = "{$row[2]}";
|
|
$name = "{$row[3]}";
|
|
$timestamp = "{$row[4]}";
|
|
$tripcode = "{$row[5]}";
|
|
$move_message = "{$row[6]}";
|
|
$edit_message = "{$row[7]}";
|
|
$original = "{$row[8]}";
|
|
}
|
|
|
|
if ( ($org_id == $original) ) {
|
|
$new_move = "system message: "
|
|
. "post $post_id from sub \"$sub\" was moved "
|
|
. "to sub \"$target_sub\"";
|
|
$new_id = make_post($db, $target_sub, $settings, $text, '');
|
|
$delete_message = "message $delete_post from sub $sub"
|
|
. " moved to $target_sub";
|
|
log_event($db, $settings, "del", $delete_message, '');
|
|
|
|
echo "<h1>$delete_message</h1>";
|
|
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET shadow = 'yes'
|
|
WHERE org_id = '$post_id'
|
|
AND sub = '$sub'");
|
|
$result = $statement->execute();
|
|
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET move_message = '$new_move',
|
|
edit_message = '$edit_message',
|
|
original = '$new_id'
|
|
WHERE post_id = '$new_id'
|
|
AND sub = '$target_sub'");
|
|
$result = $statement->execute();
|
|
|
|
if ( (!empty($name)) &&
|
|
(!empty($tripcode)) ) {
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET name = '$name',
|
|
tripcode = '$tripcode'
|
|
WHERE post_id = '$new_id'
|
|
AND sub = '$target_sub'");
|
|
$result = $statement->execute();
|
|
}
|
|
|
|
$statement = $db->prepare("SELECT post_id, org_id, text, name,
|
|
timestamp, tripcode, move_message,
|
|
edit_message
|
|
FROM threads
|
|
WHERE org_id = '$post_id'
|
|
AND post_id != '$post_id'
|
|
AND sub = '$sub'");
|
|
$result = $statement->execute();
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$post_id = "{$row[0]}";
|
|
$org_id = "{$row[1]}";
|
|
$text = "{$row[2]}";
|
|
$name = "{$row[3]}";
|
|
$timestamp = "{$row[4]}";
|
|
$tripcode = "{$row[5]}";
|
|
$move_message = "{$row[6]}";
|
|
$edit_message = "{$row[7]}";
|
|
$original = "{$row[8]}";
|
|
|
|
$new_move = "system message: "
|
|
. "post $post_id from sub \"$sub\" was moved "
|
|
. "to sub \"$target_sub\"";
|
|
$new_reply_id = make_post($db, $target_sub, $settings,
|
|
$text, $new_id);
|
|
|
|
$delete_message = "message $post_id from sub $sub moved "
|
|
. "to $target_sub";
|
|
log_event($db, $settings, "del", $delete_message, '');
|
|
|
|
echo "<h1>$delete_message</h1>";
|
|
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET shadow = 'yes'
|
|
WHERE org_id = '$post_id'
|
|
AND sub = '$sub'");
|
|
$result = $statement->execute();
|
|
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET move_message = '$new_move',
|
|
edit_message = '$edit_message',
|
|
original = '$new_id'
|
|
WHERE post_id = '$new_reply_id'
|
|
AND sub = '$target_sub'");
|
|
$result = $statement->execute();
|
|
|
|
if ( (!empty($name)) &&
|
|
(!empty($tripcode)) ) {
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET name = '$name',
|
|
tripcode = '$tripcode'
|
|
WHERE post_id = '$new_id'
|
|
AND sub = '$target_sub'");
|
|
$result = $statement->execute();
|
|
}
|
|
}
|
|
} else {
|
|
$new_move = "system message: post "
|
|
. "$post_id from sub \"$sub\" was moved "
|
|
. "to sub \"$target_sub\"";
|
|
$new_id = make_post($db, $target_sub, $settings, $text, '');
|
|
$delete_message = "message $post_id from sub $sub moved"
|
|
. " to $target_sub";
|
|
log_event($db, $settings, "del", $delete_message, '');
|
|
|
|
echo "<h1>$delete_message</h1>";
|
|
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET shadow = 'yes'
|
|
WHERE org_id = '$post_id'
|
|
AND sub = '$sub'");
|
|
$result = $statement->execute();
|
|
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET move_message = '$new_move',
|
|
edit_message = '$edit_message',
|
|
original = '$new_id'
|
|
WHERE post_id = '$new_id'
|
|
AND sub = '$target_sub'");
|
|
$result = $statement->execute();
|
|
|
|
if ( (!empty($name)) &&
|
|
(!empty($tripcode)) ) {
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET name = '$name',
|
|
tripcode = '$tripcode'
|
|
WHERE post_id = '$new_id'
|
|
AND sub = '$target_sub'");
|
|
$result = $statement->execute();
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Set the password for the admin, delete all old admin accounts
|
|
// (there can only be one...)
|
|
function set_password($db, $name, $password_hash, $token, $settings)
|
|
{
|
|
|
|
$db_token = '';
|
|
$db_name = '';
|
|
|
|
$statement = $db->prepare("SELECT name, token
|
|
FROM keys
|
|
WHERE type = 'admin'
|
|
AND name = '$name'");
|
|
$result = $statement->execute();
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$db_name = "{$row[0]}";
|
|
$db_token = "{$row[1]}";
|
|
}
|
|
|
|
if ( (!password_verify($token, $db_token)) ) {
|
|
$auth_message = "wrong combination name/token";
|
|
log_event($db, $settings, 'auth', $auth_message, '');
|
|
sleep(10);
|
|
$quit_message = "<h1>Combination of username and token is invalid."
|
|
. " This incident was logged.</h1>";
|
|
quit($db, $quit_message);
|
|
} else {
|
|
$statement = $db->prepare("UPDATE keys
|
|
SET key = '$password_hash'
|
|
WHERE name = '$name'
|
|
AND type = 'admin'");
|
|
$result = $statement->execute();
|
|
|
|
$statement = $db->prepare("DELETE FROM keys
|
|
WHERE type = 'admin'
|
|
AND name != '$name'");
|
|
$result = $statement->execute();
|
|
|
|
unlink($settings['work_dir'] . "admin_" . $name . "_token.txt");
|
|
}
|
|
|
|
}
|
|
|
|
// Show the form that allows the admin and mods to log in.
|
|
// Can be disabled in the config file.
|
|
function show_auth_form($db, $css, $settings, $type)
|
|
{
|
|
$html_string = '<h1>Give your account name and password to log in.</h1>'
|
|
. '<br><p id="page"><div class=\'form\'>';
|
|
|
|
if ( ($type == 'admin') ) {
|
|
$html_string .= '<form action=\'/a\' method=\'post\'>';
|
|
} else {
|
|
$html_string .= '<form action=\'/m\' method=\'post\'>';
|
|
}
|
|
|
|
$html_string .= '<table class=\'newpost\'>'
|
|
. '<tr><td>Name</td><td><input type=\'text\' '
|
|
. 'required name=\'auth_name\' placeholder=\'Account name\'>'
|
|
. '<tr><td>Pass</td><td><input type=\'password\' required'
|
|
. ' name=\'auth_password\' placeholder=\'Account pass\'>'
|
|
. '<input type=\'submit\' value=\'Log in\'><br></td></tr>'
|
|
. '</table></form></div><hr>';
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
// Show all posts that have been shadowed by moderators
|
|
function show_shadowed($db, $css, $settings, $token)
|
|
{
|
|
|
|
print_top_header('Shadowed messages and subs');
|
|
|
|
$statement = $db->prepare("SELECT post_id, org_id, sub, text
|
|
FROM threads
|
|
WHERE shadow = 'yes'
|
|
ORDER BY sub");
|
|
|
|
$result = $statement->execute();
|
|
|
|
$prev_sub = '';
|
|
|
|
$html_string = '';
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$post_id = "{$row[0]}";
|
|
$org_id = "{$row[1]}";
|
|
$sub = "{$row[2]}";
|
|
$text = "{$row[3]}";
|
|
$post_text = break_text(bbcode_to_html($text, $settings, $sub),
|
|
$settings);
|
|
|
|
$html_string .= "<div class='post'>"
|
|
. "<tr>"
|
|
. "<td><form action='/ush' method='post'>"
|
|
. "<input type='hidden' name='token' value=$token'>"
|
|
. "<input type='hidden' name='sub' value='$sub'>"
|
|
. "<input type='hidden' name='unshadow_id' "
|
|
. "value='$post_id'>"
|
|
. "<input type='submit' value='Unshadow post "
|
|
. "$post_id'><br></td></form>"
|
|
. "-------------------------------------"
|
|
. "<td><form action='/da' method='post'>"
|
|
. "<input type='hidden' name='token' value=$token'>"
|
|
. "<input type='hidden' name='sub' value='$sub'>"
|
|
. "<input type='hidden' name='delete_posts' "
|
|
. "value='$post_id'>"
|
|
. "<input type='submit' value='Delete post "
|
|
. "$post_id'><br></td></form><br><br>"
|
|
. "<br>$sub/$post_id<br><br><code>$post_text"
|
|
. "</code><br><br>";
|
|
|
|
if ($prev_sub != $sub) {
|
|
|
|
$html_string .= "<td><form action='/usha' method='post'>"
|
|
. "<input type='hidden' name='token' "
|
|
. "value=$token'>"
|
|
. "<input type='hidden' name='unshadow_sub' "
|
|
. "value='$sub'>"
|
|
. "<input type='submit' value='Unshadow sub "
|
|
. "$sub'><br></td></form>"
|
|
. "-------------------------------------"
|
|
. "<td><form action='/da' method='post'>"
|
|
. "<input type='hidden' name='token' "
|
|
. "value=$token'>"
|
|
. "<input type='hidden' name='sub' "
|
|
. "value='$sub'>"
|
|
. "<input type='hidden' name='delete_sub' "
|
|
. "value='$sub'>"
|
|
. "<input type='submit' value='Delete sub "
|
|
. "$sub'><br></td></form><br><br>";
|
|
}
|
|
|
|
$html_string .= '</tr></div>';
|
|
|
|
$prev_sub = $sub;
|
|
}
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
// Show the existing subs to the admin
|
|
function show_subs_admin_mod($db, $settings, $css, $token, $type)
|
|
{
|
|
if ( ($type == 'admin') ) {
|
|
$link = 'a';
|
|
} else {
|
|
$link = 'm';
|
|
}
|
|
|
|
$html_string = '<h1>';
|
|
|
|
$statement = $db->prepare("SELECT DISTINCT sub
|
|
FROM threads
|
|
WHERE shadow = 'no'
|
|
ORDER BY sub
|
|
COLLATE NOCASE");
|
|
$result = $statement->execute();
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$sub = "{$row[0]}";
|
|
$total_posts = give_total_posts($db, $sub, FALSE, $settings);
|
|
$html_string .= " | <a href=/$link/$sub/$css/$token>$sub<code>"
|
|
. "($total_posts)</code></a>";
|
|
}
|
|
|
|
$html_string .= '</h1>';
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
// Show the form that allows to apply for a moderators account.
|
|
function show_apply_form($db, $settings)
|
|
{
|
|
//rewrite to set rows ?
|
|
$html_string = '<h1>Give the desired name for your account, '
|
|
. 'an email address'
|
|
. ' (or other contact) and a password.</h1>'
|
|
. '<br><p id=\'page\'>'
|
|
. '<div class=\'form\'><form action=\'/ap\' method=\'post\'>'
|
|
. '<table class=\'newpost\'>'
|
|
. '<tr><td>Name</td><td><input type=\'text\' '
|
|
. 'required name=\'appl_name\''
|
|
. ' placeholder=\'Name of account\'>'
|
|
. '<tr><td>Email</td><td><input type=\'text\' '
|
|
. 'required name=\'appl_email\' '
|
|
. 'placeholder=\'email or other contact\'>'
|
|
. '<tr><td>Pass</td><td><input type=\'password\' '
|
|
. 'required name=\'appl_password\' placeholder=\'Min '
|
|
. '10 chars\'><input type=\'submit\' value=\'Set password\'>'
|
|
. '<br></td></tr></table></form></div><hr>';
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
// Show the form that allows to set passwords for the admin account.
|
|
function show_set_password_form($db, $settings)
|
|
{
|
|
//rewrite to set rows ?
|
|
$html_string = '<h1>Give the name of your account and the token'
|
|
.' to set your password.</h1>'
|
|
.'<br><p id=\'page\'>'
|
|
.'<div class=\'form\'><form action=\'/sp\' method=\'post\'>'
|
|
.'<table class=\'newpost\'>'
|
|
.'<tr><td>Name</td><td><input type=\'text\' '
|
|
.'required name=\'auth_name\' placeholder=\'Name of '
|
|
.'account\'><tr><td>Token</td><td><input type=\'text\' '
|
|
.'required name=\'auth_token\' placeholder=\'Put your '
|
|
.'token in here\'>'
|
|
.'<tr><td>Pass</td><td><input type=\'password\' '
|
|
.'required name=\'auth_password\' '
|
|
.'placeholder=\'Set your password\'>'
|
|
.'<input type=\'submit\' value=\'Set password\'>'
|
|
.'<br></td></tr></table></form></div><hr>';
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
// Show the form that enables the admin and the mods to delete,
|
|
// shadow or move messages and subs
|
|
function show_form_admin_mod($db, $sub, $token, $type)
|
|
{
|
|
|
|
$html_string = '<br><p id="page">';
|
|
|
|
if ( ($type == 'admin') ) {
|
|
$html_string .= '<div class=\'form\'><form action=\'/da\' '
|
|
.'method=\'post\'><table class=\'newpost\'>'
|
|
.'<tr><td>Sub to delete</td><td><textarea rows=\'1\' '
|
|
.'cols=\'56\' name=\'delete_sub\' '
|
|
.'placeholder=\'Complete sub '
|
|
.'to delete, careful with that !!!\'>'
|
|
.'</textarea></td></tr>'
|
|
.'<tr><td>Posts to delete</td><td><textarea rows=\'1\' '
|
|
.'cols=\'56\' name=\'delete_posts\' placeholder=\'IDs to '
|
|
.'delete, separate by space, or range (ex.: 7-9)\'>'
|
|
.'</textarea></td></tr>';
|
|
} else {
|
|
$html_string .= '<div class=\'form\'><form action=\'/dm\' '
|
|
. 'method=\'post\'><table class=\'newpost\'>'
|
|
. '<tr><td>Sub to delete</td><td>'
|
|
. '<textarea rows=\'1\' cols=\'56\''
|
|
. ' name=\'shadow_sub\' placeholder=\'Delete complete'
|
|
. ' sub, careful with that !!!\'></textarea></td></tr>'
|
|
. '<tr><td>Posts to delete/move</td>'
|
|
. '<td><textarea rows=\'1\''
|
|
. ' cols=\'56\' name=\'shadow_posts\' placeholder='
|
|
. '\'IDs to delete, separate by space, or range '
|
|
. '(ex.: 7-9)\'></textarea></td></tr>'
|
|
. '<tr><td>Sub to move posts to</td>'
|
|
. '<td><textarea rows=\'1\''
|
|
. ' cols=\'56\' name=\'target_sub\' placeholder='
|
|
. '\'Leave empty to delete posts\'></textarea></td></tr>';
|
|
}
|
|
|
|
$html_string .= "<input type='hidden' name='token' value=$token'>"
|
|
. "<input type='hidden' name='sub' value='$sub'>";
|
|
|
|
$html_string .= '<tr><td></td><td><input type=\'submit\' ';
|
|
|
|
if ( ($type == 'admin') ) {
|
|
$html_string .= 'value=\'Delete\'><br></td></tr>';
|
|
} else {
|
|
$html_string .= 'value=\'Delete/move\'><br></td></tr>';
|
|
}
|
|
|
|
$html_string .= '</table></form></div><hr>';
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
// Display the logs to the admin
|
|
function show_logs($db, $type, $token)
|
|
{
|
|
|
|
$logs = array();
|
|
|
|
if ($type == 'all') {
|
|
$statement = $db->prepare("SELECT timestamp, type, event, ip
|
|
FROM logs
|
|
ORDER BY unix_timestamp DESC");
|
|
} else {
|
|
$statement = $db->prepare("SELECT timestamp, type, event, ip
|
|
FROM logs
|
|
WHERE type = '$type'
|
|
ORDER BY unix_timestamp DESC");
|
|
}
|
|
|
|
$result = $statement->execute();
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
$log = array();
|
|
$timestamp = "{$row[0]}";
|
|
$log_type = "{$row[1]}";
|
|
$event = "{$row[2]}";
|
|
$ip = "{$row[3]}";
|
|
array_push($log, $timestamp, $log_type, $event, $ip);
|
|
array_push($logs, $log);
|
|
}
|
|
|
|
$html_string = '<table><tr>'
|
|
. '<th>Timestamp</th><th>Type</th>'
|
|
. '<th>Logtext</th><th>ip</th></tr>';
|
|
|
|
foreach($logs as $log_data) {
|
|
|
|
$html_string .= "<tr>"
|
|
. "<td>$log_data[0]</td>"
|
|
. "<td>$log_data[1]</td>"
|
|
. "<td>$log_data[2]</td>"
|
|
. "<td>$log_data[3]</td>"
|
|
. "</tr>";
|
|
|
|
}
|
|
|
|
$html_string .= "</table>"
|
|
. "<a href='/dl/$type/8/$token'>clear logs</a>";
|
|
// eight is the css for the admin
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
|
|
// Unshadow one post.
|
|
function unshadow_post($db, $settings, $token)
|
|
{
|
|
|
|
$post = strip_tags($_POST['unshadow_id']);
|
|
$sub = strip_tags($_POST['sub']);
|
|
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET shadow = 'no'
|
|
WHERE post_id = '$post'
|
|
AND sub = '$sub'");
|
|
|
|
$result = $statement->execute();
|
|
|
|
$unshadow_message = "message $post from sub $sub unshadowed";
|
|
log_event($db, $settings, "del", $unshadow_message, '');
|
|
|
|
$html_string = "<h1>$unshadow_message</h1>"
|
|
. "<h1>Done.</h1>"
|
|
. "<h1><a href='/sh/$sub/8/$token'>Back</a></h1>";
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
// Unshadow a whole sub.
|
|
function unshadow_sub($db, $settings, $token)
|
|
{
|
|
|
|
$sub = strip_tags($_POST['unshadow_sub']);
|
|
|
|
$statement = $db->prepare("UPDATE threads
|
|
SET shadow = 'no'
|
|
WHERE sub = '$sub'");
|
|
|
|
$result = $statement->execute();
|
|
|
|
$unshadow_message = "sub $sub unshadowed";
|
|
log_event($db, $settings, "del", $unshadow_message, '');
|
|
|
|
$html_string = "<h1>$unshadow_message</h1>"
|
|
. "<h1>Done.</h1>"
|
|
. "<h1><a href='/sh/$sub/8/$token'>Back</a></h1>";
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
// Lets the admin view the status of the mods
|
|
function view_mods($db, $css, $settings, $token)
|
|
{
|
|
|
|
$statement = $db->prepare("SELECT name, email, type
|
|
FROM keys
|
|
WHERE type in ('mod',
|
|
'application',
|
|
'disabled')");
|
|
$result = $statement->execute();
|
|
|
|
print_top_header('Moderators accounts');
|
|
|
|
$html_string = '<table><tr><td>Account name</td><td>Contact</td>'
|
|
. '<td>Status</td><td>Enable</td>'
|
|
. '<td>Disable</td><td>Delete</td>';
|
|
|
|
while ($row = $result->fetchArray(SQLITE3_NUM)) {
|
|
|
|
$name = "{$row[0]}";
|
|
$contact = "{$row[1]}";
|
|
$type = "{$row[2]}";
|
|
|
|
$html_string .= "<tr>";
|
|
$html_string .= "<td>$name</td><td>$contact</td><td>$type</td>";
|
|
|
|
if ($type != 'mod') {
|
|
$html_string .= "<td><form action='/dim' method='post'>"
|
|
. "<input type='hidden' name='token' "
|
|
. "value=$token'>"
|
|
. "<input type='hidden' name='enable_mod' "
|
|
. "value='$name'>"
|
|
. "<input type='submit' value='Enable'>"
|
|
. "<br></td></form>";
|
|
} else {
|
|
$html_string .= "<td></td>";
|
|
}
|
|
|
|
if ( ($type != 'application') && ($type != 'disabled') ) {
|
|
$html_string .= "<td><form action='/dim' method='post'>"
|
|
. "<input type='hidden' name='token' "
|
|
. "value=$token'>"
|
|
. "<input type='hidden' name='disable_mod'"
|
|
. " value='$name'>"
|
|
. "<input type='submit' value='Disable'>"
|
|
. "<br></td></form>";
|
|
} else {
|
|
$html_string .= "<td></td>";
|
|
}
|
|
|
|
$html_string .= "<td><form action='/dim' method='post'>"
|
|
. "<input type='hidden' name='token' value=$token'>"
|
|
. "<input type='hidden' name='delete_mod' value='$name'>"
|
|
. "<input type='submit' value='Delete'><br></td>"
|
|
. "</form>"
|
|
. "</tr>";
|
|
|
|
}
|
|
|
|
$html_string .= "</table></div>";
|
|
|
|
echo "$html_string";
|
|
}
|
|
|
|
// Receives an application and writes it to the db.
|
|
function set_application($db, $name, $email, $password, $settings)
|
|
{
|
|
|
|
$statement = $db->prepare("INSERT INTO keys(type, name, email, key)
|
|
VALUES ('application', '$name',
|
|
'$email', '$password')");
|
|
$statement->execute();
|
|
|
|
}
|
|
|
|
// EOF
|