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 = "

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.

"; 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 = '

Token expired.Log in ' . 'again to get a new one.' . 'This incident was logged.

'; 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 = '

Invalid token used.' . 'This incident was logged.

'; quit($db, $quit_message); } } elseif ( (!isset($_POST['auth_name'])) || (!isset($_POST['auth_password'])) ) { $quit_message = '

Please provide the name and' . ' password for your account.

'; 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 = '

Combination of password and username ' . 'is invalid. This incident was logged.

'; 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, '

Token invalid. This incident was logged.

'); } $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 = '

Token expired.Log in' . ' again to get a new one. ' . 'This incident was logged.

'; quit($db, $quit_message); } } elseif ( (!isset($_POST['auth_name'])) || (!isset($_POST['auth_password'])) ) { $quit_message = '

Please provide the name' . ' and password for your account.

'; 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 = '

Combination of password and username is' . ' invalid. This incident was logged.

'; 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, "

Sub $target_sub does not exist.

"); } } 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 .= "

$delete_message

"; } } 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 .= "

$delete_message

"; } } elseif ( (!empty($delete_array)) && ($delete_mode == 'move') ) { move_post($db, $settings, $delete_array, $sub, $target_sub, $name); } $html_string .= '

Done.

'; if ($delete_mode == 'delete') { $html_string .= "

Back

"; } else { $html_string .= "

Back

"; } 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 .= "

$delete_message

"; } 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 .= "

$delete_message

"; } $html_string .= "

Done.

"; if ($shadow_only == 'yes') { $html_string .= "

Back

"; } else { $html_string .= "

Back

"; } 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 = "
Found importfile $board_file
"; } else { $html_string = "
Could not find importfile " . "$board_file, aborting.
"; 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']; $shadow = $post['shadow']; 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', '$shadow', '$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 .= "
$import_message
"; } else { $import_message = "message $post_id from sub $sub" . " existed already and was not imported"; log_event($db, $settings, 'import', $import_message, ''); $html_string .= "
$import_message
"; } } } rename($board_file, $board_file . '.done'); $html_string .= "
Finished, imported " . "$counter messages altogether.
" . "
The boardfile was " . "renamed to avoid another import.
"; 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 "

$delete_message

"; $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 "

$delete_message

"; $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 "

$delete_message

"; $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 = "

Combination of username and token is invalid." . " This incident was logged.

"; 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 = '

Give your account name and password to log in.

' . '

'; if ( ($type == 'admin') ) { $html_string .= '
'; } else { $html_string .= ''; } $html_string .= '' . '' . '
Name' . '
Pass' . '

'; 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 .= "
" . "" . "
" . "" . "" . "" . "
" . "-------------------------------------" . "
" . "" . "" . "" . "


" . "
$sub/$post_id

$post_text" . "

"; if ($prev_sub != $sub) { $html_string .= "
" . "" . "" . "
" . "-------------------------------------" . "
" . "" . "" . "" . "


"; } $html_string .= '
'; $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 = '

'; $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 .= " | $sub" . "($total_posts)"; } $html_string .= '

'; 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 = '

Give the desired name for your account, ' . 'an email address' . ' (or other contact) and a password.

' . '

' . '

' . '' . '
Name' . '
Email' . '
Pass' . '

'; 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 = '

Give the name of your account and the token' .' to set your password.

' .'

' .'

' .'' .'
Name
Token' .'
Pass' .'' .'

'; 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 = '

'; if ( ($type == 'admin') ) { $html_string .= '

' .'' .''; } else { $html_string .= '
Sub to delete
Posts to delete
' . '' . '' . '' . '' . ''; } $html_string .= "" . ""; $html_string .= ''; } else { $html_string .= 'value=\'Delete/move\'>
'; } $html_string .= '
Sub to delete' . '
Posts to delete/move
Sub to move posts to


'; 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 = '' . '' . ''; foreach($logs as $log_data) { $html_string .= "" . "" . "" . "" . "" . ""; } $html_string .= "
TimestampTypeLogtextip
$log_data[0]$log_data[1]$log_data[2]$log_data[3]
" . "clear logs"; // 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 = "

$unshadow_message

" . "

Done.

" . "

Back

"; 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 = "

$unshadow_message

" . "

Done.

" . "

Back

"; 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 = '' . '' . ''; while ($row = $result->fetchArray(SQLITE3_NUM)) { $name = "{$row[0]}"; $contact = "{$row[1]}"; $type = "{$row[2]}"; $html_string .= ""; $html_string .= ""; if ($type != 'mod') { $html_string .= ""; } else { $html_string .= ""; } if ( ($type != 'application') && ($type != 'disabled') ) { $html_string .= ""; } else { $html_string .= ""; } $html_string .= "" . "" . ""; } $html_string .= "
Account nameContactStatusEnableDisableDelete
$name$contact$type
" . "" . "" . "" . "
" . "" . "" . "" . "
" . "" . "" . "
"; 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