<?php
/* Hook Definitions
- *
- * Hooks let you do things in your plugin, like add nav items for your
- * own pages, add extra cards to the overview and more (to come)
- */
+*
+* Hooks let you do things in your plugin, like add nav items for your
+* own pages, add extra cards to the overview and more (to come)
+*/
/** HOOKTYPE_NAVBAR
*
* @param array $pages
* See "index.php" to see how it's used.
*
*/
-
define('HOOKTYPE_PRE_OVERVIEW_CARD', 102);
+
/** HOOKTYPE_OVERVIEW_CARD
*
* @param object $stats
* The parameter is an object containing stats used in the overview.
* See "index.php" to see how it's used.
*
- */
+*/
+define('HOOKTYPE_OVERVIEW_CARD', 103);
+/** HOOKTYPE_NOTIFICATION
+ *
+ * @param array $notification
+ * The array should contain:
+ *
+ * "name" - The name of the recipient
+ * "message" - The notification message
+ *
+ * This does not do anything special by itself. It simply allows plugins
+ * to be able to use it with regards to notification sending.
+ * This is not run at any place, but should be run from your plugin.
+ *
+ * This hook is simple in design and only contains two elements in attempt
+ * to make it work cross-plugin. That is, if you have implemented your own
+ * notificiation system, you will be able to do whatever you like such as
+ * display a navbar list of notifications or send important emails by running
+ * this hook.
+ *
+*/
+define('HOOKTYPE_NOTIFICATION', 104);
-define('HOOKTYPE_OVERVIEW_CARD', 103);
+/** HOOKTYPE_PRE_FOOTER
+ * $param array $empty - Doesn't do anything
+ *
+ * This runs inside the footer body before anything else.
+ */
+define('HOOKTYPE_PRE_FOOTER', 105);
+
+/** HOOKTYPE_FOOTER
+ * $param array $empty - Doesn't do anything
+ *
+ * This runs inside the footer body after everything else.
+ */
+define('HOOKTYPE_FOOTER', 106);
+
/**
* Class for "Hook"
* This is the main function which gets called whenever you want to use a Hook.
Overall, the UnrealIRCd Web Panel is a must-have tool for any administrator managing an IRC network. Its user-friendly interface and powerful management capabilities make it easy to keep track of your network and ensure that everything is running smoothly. So why not give it a try and see how it can improve your IRC network management experience?
-## Example Overview
+## Example Overview from Desktop
<img src="https://i.ibb.co/7SdFZnk/Screenshot-from-2023-01-14-07-26-21.png">
+## Example Overview from Mobile
+<img src="https://i.ibb.co/KGLdB43/Screenshot-20230123-233804-Chrome.jpg">
+
## Prerequisites ##
- PHP 8 or later
- A webserver
--- /dev/null
+<?php
+
+define('WEBPANEL_VERSION', "1.0-git");
\ No newline at end of file
if (!is_dir(UPATH . "/vendor"))
die("The vendor/ directory is missing. Most likely the admin forgot to run 'composer install'\n");
require_once UPATH . '/vendor/autoload.php';
+require_once "cfg/defines.php";
require_once "connection.php";
require_once "misc/strings.php";
require_once "misc/user-lookup-misc.php";
require_once "Classes/class-rpc.php";
require_once "plugins.php";
-function show_nick_only($str)
-{
- $x = strpos($str, "!");
- if ($x !== false)
- $str = substr($str, 0, $x);
- return $str;
-}
-
$pages = Array(
"Overview" => "",
"Users" => "users",
"Channels" => "channels",
"Servers" => "servers",
- "Server Bans" => "server_bans.php",
+ "Server Bans" => [
+ "Server Bans" => "server-bans",
+ "Name Bans" => "server-bans/name-bans.php",
+ "Ban Exceptions" => "server-bans/ban-exceptions.php"
+ ],
"Spamfilter" => "spamfilter.php",
"News" => "news.php",
);
<div class="media">
<div class="media-body">
- <!-- This will make it so that it "works" on mobile device. Not sure it's a good idea yet though
-<meta name="viewport" content="width=device-width, initial-scale=1">
-<meta name="HandheldFriendly" content="true">
--->
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="HandheldFriendly" content="true">
+
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
<!-- Fixed navbar -->
<nav class="navbar navbar-expand-sm navbar-dark bg-dark fixed-top z-index padding-top">
- <ul class="nav navbar-nav">
- <a class="navbar-brand" href="<?php echo BASE_URL; ?>"><img src="<?php echo BASE_URL; ?>img/favicon.ico" height="25" width="25"> UnrealIRCd Admin Panel</a>
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+ <span class="navbar-toggler-icon"></span>
+ </button>
+ <div class="collapse navbar-collapse" id="collapsibleNavbar">
+ <ul class="navbar-nav mr-auto">
+ <a class="navbar-brand" href="<?php echo BASE_URL; ?>"><img src="<?php echo BASE_URL; ?>img/favicon.ico" height="25" width="25"> UnrealIRCd Admin Panel</a>
<?php
$active_page = NULL;
{
$script = $_SERVER['SCRIPT_FILENAME'];
$tok = split($script, "/");
- if (strlen($page) == 0) {
+ if (is_array($page))
+ continue;
+ if (is_string($page) && strlen($page) == 0) {
$active_page = "";
}
else if (str_ends_with($script, BASE_URL . "index.php") && BASE_URL != "/" && !strlen($tok[0]))
if (is_string($active_page) && $page == $active_page)
$class = str_replace("\"nav-item\"", "\"nav-item active\"", $class);
- echo " <li $class><a class=\"nav-link\" href=\"".BASE_URL.$page."\">$name</a></li> \n";
+ if (is_string($page))
+ echo "<li $class><a class=\"nav-link\" href=\"".BASE_URL.$page."\">$name</a></li>\n";
+
+ elseif (is_array($page))
+ {
+ foreach ($page as $k => $v)
+ {
+ $first_page = $v;
+ break;
+ }
+ ?>
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ <?php echo $name; ?>
+ </a>
+ <div class="dropdown-menu" aria-labelledby="navbarDropdown">
+ <?php foreach($page as $k => $p)
+ {
+ ?>
+ <a class="dropdown-item" href="<?php echo BASE_URL.$p;?>"><?php echo $k; ?></a>
+ <?php
+ } ?>
+ </div>
+ </li>
+ <?php
+
+ }
+
}
?>
- </ul>
+ </ul></div>
</nav><br>
</div>
?>
+<div class="container">
-<div class="container mt-5">
-
- <div class="row">
- <div class="col-sm">
+ <div class="row mt-3" style="margin-left:0px;">
+ <div class="col-sm mb-3">
<div class="card text-center">
<div class="card-header bg-success text-white">
<div class="row">
</div>
- <div class="col-sm">
+ <div class="col-sm mb-3">
<div class="card text-center">
<div class="card-header bg-primary text-white">
<div class="row">
</div>
</div>
</div>
- <div class="col-sm">
+ <div class="col-sm mb-3">
<div class="card text-center">
<div class="card-header bg-warning">
<div class="row">
</div>
</div>
- <div class="col-sm">
+ <div class="col-sm mb-3">
<div class="card text-center">
<div class="card-header bg-secondary text-white">
<div class="row">
<div class="container mt-3">
<div class="row">
- <div class="col-sm">
+ <div class="col-sm mb-3">
<div class="card text-center">
<div class="card-header bg-danger text-white">
<div class="row">
</div>
</div>
</div>
- <div class="col-sm">
+ <div class="col-sm mb-3">
<div class="card text-center">
<div class="card-header bg-secondary text-white">
<div class="row">
</div>
</div>
</div>
- <div class="col-sm">
+ <div class="col-sm mb-3">
<div class="card text-center">
<div class="card-header bg-primary text-white">
<div class="row">
else
$bg = "bg-warning";
?>
- <div class="col-sm">
+ <div class="col-sm mb-3">
<div class="card text-center">
<div class="card-header <?php echo $bg; ?> text-white">
<div class="row">
return explode($delimiter,$str);
}
+/**
+ *
+ * @param mixed $array
+ * @param mixed $delimiter
+ * @return string
+ */
function glue($array, $delimiter = " ")
{
$string = "";
return trim($string,$delimiter);
}
+/**
+ * Gets the relative path of the filename
+ * @param mixed $filename
+ * @return string
+ */
function get_relative_path($filename)
{
$relativepath = split($filename, "/");
$relativepath = glue($relativepath,"/");
return $relativepath;
}
+
+/**
+ * Returns a `nick` if the string was in the syntax:
+ * nick!ident@host
+ * @param mixed $str
+ * @return mixed
+ */
+function show_nick_only($str)
+{
+ $x = strpos($str, "!");
+ if ($x !== false)
+ $str = substr($str, 0, $x);
+ return $str;
+}
];
$conn = sqlnew();
- $query = "INSERT INTO " . SQL_PREFIX . "user_meta (user_id, meta_key, meta_value) VALUES (:id, :key, :value)";
+
+ /* check if it exists first, update it if it does */
+ $query = "SELECT * FROM " . SQL_PREFIX . "user_meta WHERE user_id = :id AND meta_key = :key";
$stmt = $conn->prepare($query);
- $stmt->execute($meta);
- if ($stmt->rowCount())
- return true;
- return false;
+ $stmt->execute(["id" => $this->id, "key" => $key]);
+ if ($stmt->rowCount()) // it exists, update instead of insert
+ {
+ $query = "UPDATE " . SQL_PREFIX . "user_meta SET meta_value = :value WHERE user_id = :id AND meta_key = :key";
+ $stmt = $conn->prepare($query);
+ $stmt->execute($meta);
+ if ($stmt->rowCount())
+ return true;
+ return false;
+ }
+ else
+ {
+ $query = "INSERT INTO " . SQL_PREFIX . "user_meta (user_id, meta_key, meta_value) VALUES (:id, :key, :value)";
+ $stmt = $conn->prepare($query);
+ $stmt->execute($meta);
+ if ($stmt->rowCount())
+ return true;
+ return false;
+ }
}
/**
- * Delete user meta data
+ * Delete user meta data by key
* @param string $key
- * @param string $value
* @return bool
*/
- function delete_meta(string $key, string $value)
+ function delete_meta(string $key)
{
- if (!$key || !$value)
+ if (!$key )
return false;
$meta = [
"id" => $this->id,
"key" => $key,
- "value" => $value
];
$conn = sqlnew();
- $query = "INSERT INTO " . SQL_PREFIX . "user_meta (user_id, meta_key, meta_value) VALUES (:id, :key, :value)";
+ $query = "DELETE FROM " . SQL_PREFIX . "user_meta WHERE user_id = :id AND meta_key = :key";
$stmt = $conn->prepare($query);
$stmt->execute($meta);
if ($stmt->rowCount())
if (!empty($_POST))
{
if ($_POST['username'] && $_POST['password'])
- {
-
- /* securitah */
- security_check();
- $user = new SQLA_User($_POST['username']);
-
- /* not being too informative with the login error in case of attackers */
- if (!$user->id)
- {
- $failmsg = "Incorrect login";
- }
- else if ($user->password_verify($_POST['password']))
- {
- $_SESSION['id'] = $user->id;
- header('Location: ' . BASE_URL);
- }
- else
- {
- $failmsg = "Incorrect login";
- }
+{
+
+ /* securitah */
+ security_check();
+ $user = new SQLA_User($_POST['username']);
+
+ /* not being too informative with the login error in case of attackers */
+ if (!$user->id)
+ {
+ $failmsg = "Incorrect login";
+ }
+ else if ($user->password_verify($_POST['password']))
+ {
+ $_SESSION['id'] = $user->id;
+ header('Location: ' . BASE_URL);
+ $user->add_meta("last_login", date("Y-m-d m:i:s"));
+ }
+ else
+ {
+ $failmsg = "Incorrect login";
+ }
}
else
Hook::func(HOOKTYPE_NAVBAR, 'sql_auth::add_navbar');
Hook::func(HOOKTYPE_PRE_HEADER, 'sql_auth::session_start');
Hook::func(HOOKTYPE_OVERVIEW_CARD, 'sql_auth::add_overview_card');
+ Hook::func(HOOKTYPE_FOOTER, 'sql_auth::add_footer_info');
if (defined('SQL_DEFAULT_USER')) // we've got a default account
{
}
}
+ public static function add_footer_info($empty)
+ {
+ if (!($user = unreal_get_current_user()))
+ return;
+
+ else {
+ echo "<code>Admin Panel v" . WEBPANEL_VERSION . "</code>";
+ }
+ }
+
public static function session_start($n)
{
do_log($_SESSION);
setting_value VARCHAR(255),
PRIMARY KEY (id)
)");
+ $conn->query("CREATE TABLE IF NOT EXISTS " . SQL_PREFIX . "fail2ban (
+ id int AUTO_INCREMENT NOT NULL,
+ ip VARCHAR(255) NOT NULL,
+ count VARCHAR(255),
+ PRIMARY KEY (id)
+ )");
new AuthSettings();
}
}
function fail2ban_check($ip)
-{}
\ No newline at end of file
+{
+
+}
\ No newline at end of file
--- /dev/null
+<?php
+require_once "../common.php";
+
+require_once "../header.php";
+
+
+$ban_exceptions = $rpc->serverbanexception()->getAll();
+
+?>
+<h4>Ban Exceptions Overview</h4>
+Here is where you can make an exception to bans, that is, to make it so that the target mask is exempt from the ban types you specify.<br>
+<br>
+
+<p><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
+ Add entry
+ </button></p></table>
+ <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="confirmModalCenterTitle" aria-hidden="true">
+ <div class="modal-dialog modal-dialog-centered" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title" id="myModalLabel">Add new Name Ban</h5>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+ <span aria-hidden="true">×</span>
+ </button>
+ </div>
+ <div class="modal-body">
+
+ <form method="post">
+ <div class="align_label">Nick / Channel</div> <input class="curvy" type="text" id="tkl_add" name="tkl_add"><br>
+
+ <div class="align_label"><label for="banlen_w">Duration: </label></div>
+ <select class="curvy" name="banlen_w" id="banlen_w">
+ <?php
+ for ($i = 0; $i <= 56; $i++)
+ {
+ if (!$i)
+ echo "<option value=\"0w\"></option>";
+ else
+ {
+ $w = ($i == 1) ? "week" : "weeks";
+ echo "<option value=\"$i" . "w\">$i $w" . "</option>";
+ }
+ }
+ ?>
+ </select>
+ <select class="curvy" name="banlen_d" id="banlen_d">
+ <?php
+ for ($i = 0; $i <= 31; $i++)
+ {
+ if (!$i)
+ echo "<option value=\"0d\"></option>";
+ else
+ {
+ $d = ($i == 1) ? "day" : "days";
+ echo "<option value=\"$i" . "d\">$i $d" . "</option>";
+ }
+ }
+ ?>
+ </select>
+ <select class="curvy" name="banlen_h" id="banlen_h">
+ <?php
+ for ($i = 0; $i <= 24; $i++)
+ {
+ if (!$i)
+ echo "<option value=\"0d\"></option>";
+ else
+ {
+ $h = ($i == 1) ? "hour" : "hours";
+ echo "<option value=\"$i" . "h\">$i $h" . "</option>";
+ }
+ }
+ ?>
+ </select>
+ <br><div class="align_label"><label for="ban_reason">Reason: </label></div>
+ <input class="curvy input_text" type="text" id="ban_reason" name="ban_reason"><br>
+ <input class="curvy input_text" type="checkbox" id="soft" name="soft">Don't affect logged-in users (soft)
+
+ </div>
+
+ <div class="modal-footer">
+ <button id="CloseButton" type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
+ <button type="submit" action="post" class="btn btn-danger">Add Ban</button>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <table class="container-xxl table table-sm table-responsive caption-top table-striped">
+ <thead class="table-primary">
+ <form method="post">
+ <th scope="col"><input type="checkbox" label='selectall' onClick="toggle_tkl(this)" /></th>
+ <th scope="col">Mask</th>
+ <th scope="col">Duration</th>
+ <th scope="col">Reason</th>
+ <th scope="col">Set By</th>
+ <th scope="col">Set On</th>
+ <th scope="col">Expires</th>
+ </thead>
+ <tbody>
+ <?php
+ foreach($ban_exceptions as $ban_exceptions)
+ {
+ $set_in_config = ((isset($ban_exceptions->set_in_config) && $ban_exceptions->set_in_config) || ($ban_exceptions->set_by == "-config-")) ? true : false;
+ echo "<tr scope='col'>";
+ if ($set_in_config)
+ echo "<td scope=\"col\"></td>";
+ else
+ echo "<td scope=\"col\"><input type=\"checkbox\" value='" . base64_encode($ban_exceptions->name).",".base64_encode($ban_exceptions->type) . "' name=\"tklch[]\"></td>";
+ echo "<td scope=\"col\">".$ban_exceptions->name."</td>";
+ echo "<td scope=\"col\">".$ban_exceptions->duration_string."</td>";
+ echo "<td scope=\"col\">".$ban_exceptions->reason."</td>";
+ $set_by = $set_in_config ? "<span class=\"badge rounded-pill badge-secondary\">Config</span>" : show_nick_only($ban_exceptions->set_by);
+ echo "<td scope=\"col\">".$set_by."</td>";
+ echo "<td scope=\"col\">".$ban_exceptions->set_at_string."</td>";
+ echo "<td scope=\"col\">".$ban_exceptions->expire_at_string."</td>";
+ echo "</tr>";
+ }
+ ?></tbody></table><p><button type="button" class="btn btn-danger" data-toggle="modal" data-target="#myModal2">
+ Delete selected
+ </button></p>
+ <div class="modal fade" id="myModal2" tabindex="-1" role="dialog" aria-labelledby="confirmModalCenterTitle" aria-hidden="true">
+ <div class="modal-dialog modal-dialog-centered" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title" id="myModalLabel">Confirm deletion</h5>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+ <span aria-hidden="true">×</span>
+ </button>
+ </div>
+ <div class="modal-body">
+ Are you sure you want to do this?<br>
+ This cannot be undone.
+ </div>
+ <div class="modal-footer">
+ <button id="CloseButton" type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
+ <button type="submit" action="post" class="btn btn-danger">Delete</button>
+
+ </div>
+ </div>
+ </div>
+ </div></form></div></div>
+
+<?php require_once 'footer.php'; ?>
<?php
-require_once "common.php";
+require_once "../common.php";
-require_once "header.php";
+require_once "../header.php";
if (!empty($_POST))
{
}
$tkl = $rpc->serverban()->getAll();
-foreach ($rpc->nameban()->getAll() as $v)
- $tkl[] = $v;
foreach ($rpc->serverbanexception()->getAll() as $v)
$tkl[] = $v;
?>
-<h4>Server Bans Overview</h4><br>
+<h4>Server Bans Overview</h4>
+Here are all your network bans, from K-Lines to G-Lines, it's all here.<br><br>
<p><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
Add entry
</button></p></table>
--- /dev/null
+<?php
+require_once "../common.php";
+
+require_once "../header.php";
+
+if (!empty($_POST))
+{
+
+ do_log($_POST);
+
+ if (isset($_POST['tklch']) && !empty($_POST['tklch'])) // User has asked to delete these tkls
+ {
+ foreach ($_POST['tklch'] as $key => $value)
+ {
+ $tok = base64_decode($value);
+ $success = false;
+ $success = $rpc->nameban()->delete($tok);
+
+
+ if ($success)
+ Message::Success("Name Ban has been removed for $tok");
+ else
+ Message::Fail("Unable to remove Name Ban on $tok: $rpc->error");
+ }
+ }
+ elseif (isset($_POST['tkl_add']) && !empty($_POST['tkl_add']))
+ {
+ if (!($iphost = $_POST['tkl_add']))
+ Message::Fail("No mask was specified");
+
+ /* duplicate code for now [= */
+ $banlen_w = (isset($_POST['banlen_w'])) ? $_POST['banlen_w'] : NULL;
+ $banlen_d = (isset($_POST['banlen_d'])) ? $_POST['banlen_d'] : NULL;
+ $banlen_h = (isset($_POST['banlen_h'])) ? $_POST['banlen_h'] : NULL;
+ $duration = "";
+ if (!$banlen_d && !$banlen_h && !$banlen_w)
+ $duration .= "0";
+ else {
+ if ($banlen_w)
+ $duration .= $banlen_w;
+ if ($banlen_d)
+ $duration .= $banlen_d;
+ if ($banlen_h)
+ $duration .= $banlen_h;
+ }
+ $msg_msg = ($duration == "0" || $duration == "0w0d0h") ? "permanently" : "for " . rpc_convert_duration_string($duration);
+ $reason = (isset($_POST['ban_reason'])) ? $_POST['ban_reason'] : "No reason";
+
+ if ($rpc->nameban()->add($iphost, $reason, $duration))
+ Message::Success("Name Ban set against \"$iphost\": $reason");
+ else
+ Message::Fail("Name Ban could not be set against \"$iphost\": $rpc->error");
+
+ }
+ elseif (isset($_POST['search_types']) && !empty($_POST['search_types']))
+ {
+
+ }
+}
+
+
+$name_bans = $rpc->nameban()->getAll();
+
+?>
+<h4>Name Bans Overview</h4>
+Here you can essentially forbid the use of a nick or channel name. This is useful to reserve services nicks so they cannot be used by normal users.<br>
+You can also forbid the use of channel names. This is useful in such cases where an admin might need to close a channel for reasons relating to their own policy.<br>
+<br>
+<p><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
+ Add entry
+ </button></p></table>
+ <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="confirmModalCenterTitle" aria-hidden="true">
+ <div class="modal-dialog modal-dialog-centered" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title" id="myModalLabel">Add new Name Ban</h5>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+ <span aria-hidden="true">×</span>
+ </button>
+ </div>
+ <div class="modal-body">
+
+ <form method="post">
+ <div class="align_label">Nick / Channel</div> <input class="curvy" type="text" id="tkl_add" name="tkl_add"><br>
+
+ <div class="align_label"><label for="banlen_w">Duration: </label></div>
+ <select class="curvy" name="banlen_w" id="banlen_w">
+ <?php
+ for ($i = 0; $i <= 56; $i++)
+ {
+ if (!$i)
+ echo "<option value=\"0w\"></option>";
+ else
+ {
+ $w = ($i == 1) ? "week" : "weeks";
+ echo "<option value=\"$i" . "w\">$i $w" . "</option>";
+ }
+ }
+ ?>
+ </select>
+ <select class="curvy" name="banlen_d" id="banlen_d">
+ <?php
+ for ($i = 0; $i <= 31; $i++)
+ {
+ if (!$i)
+ echo "<option value=\"0d\"></option>";
+ else
+ {
+ $d = ($i == 1) ? "day" : "days";
+ echo "<option value=\"$i" . "d\">$i $d" . "</option>";
+ }
+ }
+ ?>
+ </select>
+ <select class="curvy" name="banlen_h" id="banlen_h">
+ <?php
+ for ($i = 0; $i <= 24; $i++)
+ {
+ if (!$i)
+ echo "<option value=\"0d\"></option>";
+ else
+ {
+ $h = ($i == 1) ? "hour" : "hours";
+ echo "<option value=\"$i" . "h\">$i $h" . "</option>";
+ }
+ }
+ ?>
+ </select>
+ <br><div class="align_label"><label for="ban_reason">Reason: </label></div>
+ <input class="curvy input_text" type="text" id="ban_reason" name="ban_reason"><br>
+
+ </div>
+
+ <div class="modal-footer">
+ <button id="CloseButton" type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
+ <button type="submit" action="post" class="btn btn-danger">Add Ban</button>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <table class="container-xxl table table-sm table-responsive caption-top table-striped">
+ <thead class="table-primary">
+ <form method="post" action="name-bans.php">
+ <th scope="col"><input type="checkbox" label='selectall' onClick="toggle_tkl(this)" /></th>
+ <th scope="col">Mask</th>
+ <th scope="col">Duration</th>
+ <th scope="col">Reason</th>
+ <th scope="col">Set By</th>
+ <th scope="col">Set On</th>
+ <th scope="col">Expires</th>
+ </thead>
+ <tbody>
+ <?php
+ foreach($name_bans as $name_bans)
+ {
+ $set_in_config = ((isset($name_bans->set_in_config) && $name_bans->set_in_config) || ($name_bans->set_by == "-config-")) ? true : false;
+ echo "<tr scope='col'>";
+ if ($set_in_config)
+ echo "<td scope=\"col\"></td>";
+ else
+ echo "<td scope=\"col\"><input type=\"checkbox\" value='" . base64_encode($name_bans->name)."' name=\"tklch[]\"></td>";
+ echo "<td scope=\"col\">".$name_bans->name."</td>";
+ echo "<td scope=\"col\">".$name_bans->duration_string."</td>";
+ echo "<td scope=\"col\">".$name_bans->reason."</td>";
+ $set_by = $set_in_config ? "<span class=\"badge rounded-pill badge-secondary\">Config</span>" : show_nick_only($name_bans->set_by);
+ echo "<td scope=\"col\">".$set_by."</td>";
+ echo "<td scope=\"col\">".$name_bans->set_at_string."</td>";
+ echo "<td scope=\"col\">".$name_bans->expire_at_string."</td>";
+ echo "</tr>";
+ }
+ ?></tbody></table><p><button type="button" class="btn btn-danger" data-toggle="modal" data-target="#myModal2">
+ Delete selected
+ </button></p>
+ <div class="modal fade" id="myModal2" tabindex="-1" role="dialog" aria-labelledby="confirmModalCenterTitle" aria-hidden="true">
+ <div class="modal-dialog modal-dialog-centered" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title" id="myModalLabel">Confirm deletion</h5>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+ <span aria-hidden="true">×</span>
+ </button>
+ </div>
+ <div class="modal-body">
+ Are you sure you want to do this?<br>
+ This cannot be undone.
+ </div>
+ <div class="modal-footer">
+ <button id="CloseButton" type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
+ <button type="submit" action="post" class="btn btn-danger">Delete</button>
+
+ </div>
+ </div>
+ </div>
+ </div></form></div></div>
+
+<?php require_once 'footer.php'; ?>