Compare commits

..

No commits in common. "master" and "v2.0.0-beta7" have entirely different histories.

32 changed files with 582 additions and 1406 deletions

4
.gitignore vendored
View File

@ -1,4 +0,0 @@
config.php
.idea/
.vscode/
.code/

View File

@ -1,7 +1,4 @@
<?php <?php
define("NAME", "");
define("TITLE", "");
define("WEB_URL", "");
require_once("template.php"); require_once("template.php");
if (!file_exists("config.php")) if (!file_exists("config.php"))
{ {

View File

@ -1,32 +0,0 @@
FROM php:8.2-apache
RUN docker-php-ext-install mysqli
RUN docker-php-ext-enable mysqli
RUN apt-get update
RUN apt-get install libzip-dev -y
RUN docker-php-ext-install zip
RUN docker-php-ext-enable zip
RUN a2enmod rewrite
RUN touch /usr/local/etc/php/conf.d/ssp.ini
RUN echo "output_buffering = 16384" >> /usr/local/etc/php/conf.d/ssp.ini
RUN echo "display_errors = off" >> /usr/local/etc/php/conf.d/ssp.ini
RUN echo "error_reporting = E_ERROR" >> /usr/local/etc/php/conf.d/ssp.ini
RUN apt install git -y
WORKDIR /var/www/html
RUN docker-php-ext-install gettext
RUN docker-php-ext-install pdo_mysql
RUN apt-get update && apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev && docker-php-ext-configure gd --with-freetype --with-jpeg && docker-php-ext-install -j$(nproc) gd
RUN apt-get install -y locales
RUN locale-gen en_GB.UTF-8
RUN sed -i '/en_GB.UTF-8/s/^# //g' /etc/locale.gen && \
locale-gen
RUN apt-get install -y curl
# And clean up the image
RUN rm -rf /var/lib/apt/lists/*
RUN curl -Lsf 'https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz' | tar -C '/usr/local' -xvzf -
ENV PATH /usr/local/go/bin:$PATH
RUN go get github.com/mailhog/mhsendmail
RUN cp /root/go/bin/mhsendmail /usr/bin/mhsendmail
RUN echo 'sendmail_path = /usr/bin/mhsendmail --smtp-addr mailhog:1025' > /usr/local/etc/php/php.ini

View File

@ -1,19 +1,19 @@
# Server Status (Official) # Server Status Beta (Official)
## This is the official Server Status Project. ## This is the official beta fork of Server Status by the contributors.
![License](https://img.shields.io/github/license/Pryx/server-status.svg) ![Current release](https://img.shields.io/badge/version-2-blue) ![License](https://img.shields.io/github/license/Pryx/server-status.svg) ![Current release](https://img.shields.io/badge/version-2-blue)
![Beta-Build](https://img.shields.io/badge/latest_beta-Developmet_Beta_7-black) ![Beta-Build](https://img.shields.io/badge/latest_beta-Developmet_Beta_6-black)
![Stability](https://img.shields.io/badge/master_stability-Stable-red) ![Beta-Stability](https://img.shields.io/badge/Beta_Stability-Unusable-red)
![Stability](https://img.shields.io/badge/master_stability-Unstable-red)
![Build](https://img.shields.io/badge/build-success-green) ![Build](https://img.shields.io/badge/build-success-green)
<!--
## What does **contributor beta** mean? ## What does **contributor beta** mean?
It means the beta that is heavily unstable that is meant for contributors to make changes and use as a recovery point. It means the beta that is heavily unstable that is meant for contributors to make changes and use as a recovery point.
### Other Beta Types ### Other Beta Type
#### Development Beta #### Development Beta
##### This beta has some bugs that are noticeable and is sometimes unstable. Best for new contributors ##### This beta has some bugs that are noticeable and is sometimes unstable. Best for new contributors
#### Public Beta #### Public Beta
##### This beta has some bugs that are not really noticeable and mostly exist as bugs. Best for trying the new features before updating! ##### This beta has some bugs that are not really noticeable and mostly exist as bugs. Best for trying the new features before updating!
--> Very simple server status page written in PHP that can run on **PHP 5.4+** - even on **shared webhosting** even without shell access. Because why waste your money on another server (or host on a server that you might want to do maintenance on), when you can use cheap webhosting? And as a cherry on top - it works even without javascript!
Very simple server status page written in PHP that can run on **PHP 5.5+** - even on **shared webhosting** even without shell access. Because why waste your money on another server (or host on a server that you might want to do maintenance on), when you can use cheap webhosting? And as a cherry on top - it works even without javascript!
## How do I install this thing? ## How do I install this thing?
Simply put the files on your server and access it from your browser. There will be a simple install dialog waiting for you. Simply put the files on your server and access it from your browser. There will be a simple install dialog waiting for you.

View File

@ -1,15 +0,0 @@
# Security Policy
## Supported Versions
Only the latest version of server-status is being supported. Older versions won't recieve security updates.
## Reporting a Vulnerability
If you believe that you have have discovered a vulnerability you can report it by emailing the [lead maintainer](https://github.com/Pryx) at vojtech@sajdl.com.
Please include the keyword VULNERABILITY and the repository name in the subject of the email.
In the email, please describe your findings, the project versions you tested and were affected by the vulnerability and also include the full steps to reproduce it.
We appreciate your efforts to make server-status more secure and will try to do everytihing in our power to get the issues resolved as fast as possible. We will
keep you informed of the progress towards a fix.

View File

@ -110,16 +110,6 @@ else{
require_once("new-user.php"); require_once("new-user.php");
break; break;
case 'new-service':
case 'edit-service':
require_once('service.php');
break;
case 'new-service-group':
case 'edit-service-group':
require_once('service-group.php');
break;
case 'options': case 'options':
require_once("options.php"); require_once("options.php");
break; break;

View File

@ -1,99 +0,0 @@
<?php
if (isset($_GET['new']))
{
ServiceGroup::add();
}
if (isset($_GET['edit']))
{
ServiceGroup::edit();
}
if (isset($_GET['delete']))
{
ServiceGroup::delete();
}
$boolEdit = false;
$group_value = isset($_POST['group']) ? $_POST['group'] : '';
$description_value = isset($_POST['description']) ? $_POST['description'] : '';
$visibility_id_value = isset($_POST['visibility_id']) ? $_POST['visibility_id'] : '';
if ( isset($_GET['id']) && !isset($_POST['id']) ) {
$group_id = (int) $_GET['id'];
$boolEdit = true;
$stmt = $mysqli->prepare("SELECT * FROM services_groups WHERE id LIKE ?");
$stmt->bind_param("i", $group_id);
$stmt->execute();
$query = $stmt->get_result();
$data = $query->fetch_assoc();
$group_value = $data['name'];
$description_value = $data['description'];
$visibility_id_value = $data['visibility'];
}
if (!$boolEdit) {
Template::render_header(_("New service group"), true); ?>
<div class="text-center">
<h2><?php echo _("Add new service group");?></h2>
</div>
<?php
$form_url = WEB_URL .'/admin/?do=new-service-group&amp;new=group';
} else {
Template::render_header(_("Edit service group"), true); ?>
<div class="text-center">
<h2><?php echo _("Edit service group");?></h2>
</div>
<?php
$form_url = WEB_URL .'/admin/?do=edit-service-group&amp;edit&amp;id='.$group_id;
}
?>
<form action="<?php echo $form_url;?>" method="POST" class="form-horizontal">
<?php if (isset($message))
{?>
<p class="alert alert-danger"><?php echo $message?></p>
<?php
} ?>
<div class="form-group">
<div class="col-sm-6"><label for="group"><?php echo _("Service Group Name");?>: </label><input type="text" maxlength="50" name="group" value="<?php echo ((isset($_POST['group']))?htmlspecialchars($_POST['group'],ENT_QUOTES):$group_value);?>" id="group" placeholder="<?php echo _("service group name");?>" class="form-control" required></div>
<div class="col-sm-6"><label for="description"><?php echo _("Description");?>: </label><input type="text" maxlength="100" name="description" value="<?php echo ((isset($_POST['description']))?htmlspecialchars($description_value,ENT_QUOTES):$description_value);?>" id="description" placeholder="<?php echo _("Description");?>" class="form-control"></div>
</div>
<div class="form-group">
<div class="col-sm-6">
<label for="visibility_id"><?php echo _("Visibility");?>: </label>
<select name="visibility_id" id="visibility_id" class="form-control">
<?php
if (!empty($visibility_id_value))
{
$visibility_id = $visibility_id_value;
}
else
{
$visibility_id = null;
}
//$visibilitys = Service::get_groups();
foreach ($visibility as $key => $value) {
if ($visibility_id == $key)
{
echo '<option value="'.$key.'" selected>'.$value.'</option>';
}
else{
echo '<option value="'.$key.'">'.$value.'</option>';
}
}
?>
</select>
</div>
</div>
<?php
if ( $boolEdit ) {
echo '<input type="hidden" id="id" name="id" value="'.$group_id.'">';
}
?>
<button type="submit" class="btn btn-primary pull-right"><?php echo _("Submit");?></button>
</form>

View File

@ -1,97 +0,0 @@
<?php
if (isset($_GET['new']))
{
Service::add();
}
if (isset($_GET['edit']))
{
Service::edit();
}
/*if (isset($_GET['delete']))
{
Service::delete();
}*/
$boolEdit = false;
$service_value = isset($_POST['service']) ? $_POST['service'] : '';
$description_value = isset($_POST['description']) ? $_POST['description'] : '';
$group_id_value = isset($_POST['group_id']) ? $_POST['group_id'] : '';
if ( isset($_GET['id']) && !isset($_POST['id']) ) {
$service_id = (int) $_GET['id'];
$boolEdit = true;
$stmt = $mysqli->prepare("SELECT * FROM services WHERE id LIKE ?");
$stmt->bind_param("i", $service_id);
$stmt->execute();
$query = $stmt->get_result();
$data = $query->fetch_assoc();
//print_r($data);
$service_value = $data['name'];
$description_value = $data['description'];
$group_id_value = $data['group_id'];
}
if (!$boolEdit) {
Template::render_header(_("New service"), true); ?>
<div class="text-center">
<h2><?php echo _("Add new service");?></h2>
</div>
<?php
$form_url = WEB_URL . '/admin/?do=new-service&amp;new=service';
} else {
Template::render_header(_("New service"), true); ?>
<div class="text-center">
<h2><?php echo _("Add new service");?></h2>
</div>
<?php
$form_url = WEB_URL . '/admin/?do=edit-service&amp;edit&amp;id='.$service_id;
}
?>
<form action="<?php echo $form_url;?>" method="POST" class="form-horizontal">
<?php if (isset($message))
{?>
<p class="alert alert-danger"><?php echo $message?></p>
<?php
} ?>
<div class="form-group">
<div class="col-sm-6"><label for="service"><?php echo _("Service");?>: </label><input type="text" maxlength="50" name="service" value="<?php echo ((isset($_POST['service']))?htmlspecialchars($_POST['service'],ENT_QUOTES):$service_value);?>" id="service" placeholder="<?php echo _("service");?>" class="form-control" required></div>
<div class="col-sm-6"><label for="description"><?php echo _("Description");?>: </label><input type="text" maxlength="200" name="description" value="<?php echo ((isset($_POST['description']))?htmlspecialchars($_POST['description'],ENT_QUOTES):$description_value);?>" id="description" placeholder="<?php echo _("Description");?>" class="form-control"></div>
</div>
<div class="form-group">
<div class="col-sm-6">
<label for="group_id"><?php echo _("Service Group");?>: </label>
<select name="group_id" id="group_id" class="form-control">
<?php
if (!empty($group_id_value))
{
$group_id = $group_id_value;
}
else
{
$group_id = null;
}
$groups = ServiceGroup::get_groups();
foreach ($groups as $key => $value) {
if ($group_id == $key)
{
echo '<option value="'.$key.'" selected>'.$value.'</option>';
}
else{
echo '<option value="'.$key.'">'.$value.'</option>';
}
}
?>
</select>
</div>
</div>
<?php
if ( $boolEdit ) {
echo '<input type="hidden" id="id" name="id" value="'.$service_id.'">';
}
?>
<button type="submit" class="btn btn-primary pull-right"><?php echo _("Submit");?></button>
</form>

View File

@ -1,12 +1,12 @@
<?php <?php
if (isset($_GET['delete']) && isset($_GET['type'])) if (isset($_GET['new']))
{
Service::add();
}
if (isset($_GET['delete']))
{ {
if ( $_GET['type'] == 'service') {
Service::delete(); Service::delete();
}
elseif ( $_GET['type'] == 'groups') {
ServiceGroup::delete();
}
} }
Template::render_header(_("Settings"), true); Template::render_header(_("Settings"), true);
@ -24,7 +24,10 @@ if (isset($message)){
<?php if ($user->get_rank() <= 1){?> <?php if ($user->get_rank() <= 1){?>
<form action="?do=settings&new=service" method="post"> <form action="?do=settings&new=service" method="post">
<div class="input-group pull-right new-service"> <div class="input-group pull-right new-service">
<a href="<?php echo WEB_URL;?>/admin/?do=new-service" class="btn btn-success pull-right"><?php echo _("Add new service");?></a> <input class="form-control" name="service" placeholder="Name" type="text" value="<?php echo ((isset($_POST['service']))?htmlspecialchars($_POST['service']):''); ?>" maxlength="50" required>
<span class="input-group-btn">
<button type="submit" class="btn btn-success pull-right"><?php echo _("Add service");?></button>
</span>
</div> </div>
</form> </form>
<?php }?> <?php }?>
@ -32,10 +35,8 @@ if (isset($message)){
<table class="table"> <table class="table">
<thead><tr> <thead><tr>
<!--<th scope="col"><?php echo _("ID");?></th>--> <th scope="col"><?php echo _("ID");?></th>
<th scope="col"><?php echo _("Name");?></th> <th scope="col"><?php echo _("Name");?></th>
<th scope="col"><?php echo _("Description");?></th>
<th scope="col"><?php echo _("Group");?></th>
<?php if ($user->get_rank()<=1) <?php if ($user->get_rank()<=1)
{?> {?>
<th scope="col"><?php echo _("Delete");?></th> <th scope="col"><?php echo _("Delete");?></th>
@ -44,65 +45,15 @@ if (isset($message)){
</thead> </thead>
<tbody> <tbody>
<?php <?php
$query = $mysqli->query("SELECT services.*, services_groups.name AS group_name FROM `services` LEFT JOIN services_groups ON services.group_id = services_groups.id ORDER BY services.name ASC"); $query = $mysqli->query("SELECT * FROM services");
while($result = $query->fetch_assoc()) while($result = $query->fetch_assoc())
{ {
echo "<tr>"; echo "<tr>";
//echo "<td>".$result['id']."</td>"; echo "<td>".$result['id']."</td>";
echo '<td><a href="'.WEB_URL.'/admin?do=edit-service&id='.$result['id'].'">'.$result['name'].'</a></th>'; echo "<td>".$result['name']."</td>";
echo "<td>".$result['description']."</td>";
echo "<td>".$result['group_name']."</td>";
if ($user->get_rank()<=1) if ($user->get_rank()<=1)
{ {
echo '<td><a href="'.WEB_URL.'/admin/?do=settings&type=service&delete='.$result['id'].'" class="pull-right delete-service"><i class="fa fa-trash"></i></a></td>'; echo '<td><a href="'.WEB_URL.'/admin/?do=settings&delete='.$result['id'].'" class="pull-right delete-service"><i class="fa fa-trash"></i></a></td>';
}
echo "</tr>";
}?>
</tbody>
</table>
</div>
</section>
<section>
<h3 class="pull-left"><?php echo _("Services Groups");?></h3>
<?php if ($user->get_rank() <= 1){?>
<form action="?do=settings&new=service-group" method="post">
<div class="input-group pull-right new-service">
<a href="<?php echo WEB_URL;?>/admin/?do=new-service-group" class="btn btn-success pull-right"><?php echo _("Add new service group");?></a>
</div>
</form>
<?php }?>
<div class="table-responsive">
<table class="table">
<thead><tr>
<!--<th scope="col"><?php echo _("ID");?></th>-->
<th scope="col"><?php echo _("Group Name");?></th>
<th scope="col"><?php echo _("In use by");?></th>
<th scope="col"><?php echo _("Description");?></th>
<th scope="col"><?php echo _("Visibility");?></th>
<?php if ($user->get_rank()<=1)
{?>
<th scope="col"><?php echo _("Delete");?></th>
<?php } ?>
</tr>
</thead>
<tbody>
<?php
$query = $mysqli->query("SELECT sg.* , (SELECT COUNT(*) FROM services WHERE services.group_id = sg.id) AS counter FROM services_groups AS sg ORDER BY sg.id ASC");
while($result = $query->fetch_assoc())
{
echo "<tr>";
//echo "<td>".$result['id']."</td>";
echo '<td><a href="'.WEB_URL.'/admin?do=edit-service-group&id='.$result['id'].'">'.$result['name'].'</a></th>';
echo '<td> <span class="badge badge-danger ml-2">'.$result['counter'].'</span>';
echo "<td>".$result['description']."</td>";
echo "<td>".$visibility[$result['visibility']]."</td>";
if ($user->get_rank()<=1)
{
echo '<td><a href="'.WEB_URL.'/admin/?do=settings&type=groups&delete='.$result['id'].'" class="pull-right delete-service"><i class="fa fa-trash"></i></a></td>';
} }
echo "</tr>"; echo "</tr>";
}?> }?>

View File

@ -47,7 +47,7 @@ Template::render_header(_("User"), true);
?> ?>
<div class="text-center"> <div class="text-center">
<h1><?php <h1><?php
if (isset($_GET['id']) && isset($_SESSION['user']) && $_SESSION['user'] == $_GET['id']) if ($_SESSION['user'] == $_GET['id'])
{ {
echo _("User settings"); echo _("User settings");
}else{ }else{

View File

@ -15,25 +15,26 @@ else{
$array = $constellation->render_status(true, false); $array = $constellation->render_status(true, false);
echo json_encode($array); echo json_encode($array);
}else{ }else{
// get id of service, check if service exists $query = $mysqli->prepare("SELECT name FROM services WHERE id=?");
$queryId = $mysqli->prepare("SELECT id from services where id = ?;"); $query->bind_param("i", $_GET['id']);
$queryId->bind_param("i", $_GET['id']); $query->execute();
$queryId->execute(); $result = $query->get_result()->fetch_assoc();
$result = $queryId->get_result()->fetch_assoc();
if (!count($result)) if (!count($result))
{ {
die(json_encode(["error" => _("Service does not exist!")])); die(json_encode(["error" => _("Service does not exist!")]));
} }
// get name, description and status.type (status of service) by id
$query = $mysqli->prepare("select services.id, name, description, status.type from services inner join status on status.id = services.id where services.id = ?;"); $sql = $mysqli->prepare("SELECT type FROM services_status INNER JOIN status ON services_status.status_id = status.id WHERE service_id = ? AND `time` <= ? AND (`end_time` >= ? OR `end_time`=0) ORDER BY `time` DESC LIMIT 1");
$query->bind_param("i", $_GET['id']);
$query->execute(); $sql->bind_param("iii", $id, $timestamp, $timestamp);
$result = $query->get_result()->fetch_assoc(); $sql->execute();
// if type is a number then return it, else just return the service name/desc $tmp = $sql->get_result();
if (is_numeric($result["type"])) { if ($tmp->num_rows)
$service = new Service($_GET["id"], $result["name"], $result["description"], '', $result["type"]); {
} else { $service = new Service($_GET['id'], $result['name'], $tmp->fetch_assoc()['type']);
$service = new Service($_GET["id"], $result["name"], $result["description"]); }
else{
$service = new Service($_GET['id'], $result['name']);
} }
echo json_encode($service); echo json_encode($service);

View File

@ -2,7 +2,6 @@
//DIR Because of include problems //DIR Because of include problems
require_once(__DIR__ . "/incident.php"); require_once(__DIR__ . "/incident.php");
require_once(__DIR__ . "/service.php"); require_once(__DIR__ . "/service.php");
require_once(__DIR__ . "/service-group.php");
require_once(__DIR__ . "/user.php"); require_once(__DIR__ . "/user.php");
require_once(__DIR__ . "/token.php"); require_once(__DIR__ . "/token.php");
/** /**
@ -69,11 +68,10 @@ class Constellation
* @param boolean $admin * @param boolean $admin
* @return array of services * @return array of services
*/ */
public function render_status($admin = false, $heading = true): array{ public function render_status($admin = false, $heading = true){
global $mysqli; global $mysqli;
//$query = $mysqli->query("SELECT id, name, description FROM services"); $query = $mysqli->query("SELECT id, name FROM services");
$query = $mysqli->query("SELECT services.id, services.name, services.description, services_groups.name as group_name FROM services LEFT JOIN services_groups ON services.group_id=services_groups.id ORDER BY services_groups.name ASC, services.name;");
$array = array(); $array = array();
if ($query->num_rows){ if ($query->num_rows){
$timestamp = time(); $timestamp = time();
@ -88,10 +86,10 @@ class Constellation
$tmp = $sql->get_result(); $tmp = $sql->get_result();
if ($tmp->num_rows) if ($tmp->num_rows)
{ {
$array[] = new Service($result['id'], $result['name'], $result['description'], $result['group_name'], $tmp->fetch_assoc()['type']); $array[] = new Service($result['id'], $result['name'], $tmp->fetch_assoc()['type']);
} }
else{ else{
$array[] = new Service($result['id'], $result['name'], $result['description'], $result['group_name']); $array[] = new Service($result['id'], $result['name']);
} }
} }
if ($heading) if ($heading)
@ -104,12 +102,11 @@ class Constellation
} }
if (!$admin) if (!$admin)
{ {
echo '<div id="status-container" class="clearfix">';
foreach($array as $service){ foreach($array as $service){
$service->render(); $service->render();
} }
echo '</ul>'; echo '</div>';
return $array;
} }
else{ else{
return $array; return $array;

View File

@ -223,7 +223,7 @@ class Incident implements JsonSerializable
<?php <?php
} }
public function jsonSerialize():mixed { public function jsonSerialize() {
return [ return [
"id" => $this->id, "id" => $this->id,
"date" => $this->timestamp, "date" => $this->timestamp,

View File

@ -150,6 +150,7 @@ class LocaleNegotiator
'nl_BE' => 'Nederlands', 'nl_BE' => 'Nederlands',
'nl_NL' => 'Nederlands', 'nl_NL' => 'Nederlands',
'nn_NO' => 'Nynorsk', 'nn_NO' => 'Nynorsk',
'nb_NO' => 'Norsk Bokmål',
'nso_ZA' => 'Northern sotho', 'nso_ZA' => 'Northern sotho',
'oc_FR' => 'Occitan', 'oc_FR' => 'Occitan',
'or_IN' => 'ଓଡ଼ିଆ', 'or_IN' => 'ଓଡ଼ିଆ',

View File

@ -60,11 +60,6 @@ class Notification
$sql = "SELECT DISTINCT subscriberIDFK FROM services_subscriber WHERE serviceIDFK IN (" . $this->serviceids . ")"; $sql = "SELECT DISTINCT subscriberIDFK FROM services_subscriber WHERE serviceIDFK IN (" . $this->serviceids . ")";
$query = $mysqli->query($sql); $query = $mysqli->query($sql);
if (0 === $query->num_rows) {
// skip processing if no one needs to be notified
return;
}
// Create the queue tasks for email/telegram notifications // Create the queue tasks for email/telegram notifications
$queue = new Queue(); $queue = new Queue();
$queue->status = $queue->all_status['populating']; $queue->status = $queue->all_status['populating'];
@ -130,7 +125,7 @@ class Notification
* @param string $msg Body of message * @param string $msg Body of message
* @return boolean true = Sent / False = failed * @return boolean true = Sent / False = failed
*/ */
public static function submit_queue_telegram($userID, $firstname, $msg) public function submit_queue_telegram($userID, $firstname, $msg)
{ {
// TODO Handle limitations (Max 30 different subscribers per second) // TODO Handle limitations (Max 30 different subscribers per second)
// TODO Error handling // TODO Error handling
@ -155,7 +150,7 @@ class Notification
* @param String $uthkey Users token for managing subscription * @param String $uthkey Users token for managing subscription
* @return void * @return void
*/ */
public static function submit_queue_email($subscriber, $subject, $msg): bool public function submit_queue_email($subscriber, $subject, $msg)
{ {
// TODO Error handling // TODO Error handling
$mailer = new Mailer(); $mailer = new Mailer();

View File

@ -49,7 +49,7 @@ class Queue
* Remove task from the queue * Remove task from the queue
* @return void * @return void
*/ */
public static function delete_task($task_id){ public function delete_task($task_id){
global $mysqli; global $mysqli;
$stmt = $mysqli->prepare("DELETE FROM queue_task WHERE id = ?"); $stmt = $mysqli->prepare("DELETE FROM queue_task WHERE id = ?");
$stmt->bind_param("i", $task_id); $stmt->bind_param("i", $task_id);
@ -98,14 +98,14 @@ class Queue
$this->set_task_status($this->all_status['ready']); // Make task available for release $this->set_task_status($this->all_status['ready']); // Make task available for release
} }
public static function update_notification_retries($task_id, $subscriber_id) { public function update_notification_retries($task_id, $subscriber_id) {
global $mysqli; global $mysqli;
$stmt = $mysqli->prepare("UPDATE queue_notify SET retries = retries+1 WHERE task_id = ? AND subscriber_id = ?"); $stmt = $mysqli->prepare("UPDATE queue_notify SET retries = retries+1 WHERE task_id = ? AND subscriber_id = ?");
$stmt->bind_param("ii", $task_id, $subscriber_id); $stmt->bind_param("ii", $task_id, $subscriber_id);
$stmt->execute(); $stmt->execute();
} }
public static function delete_notification($task_id, $subscriber_id) { public function delete_notification($task_id, $subscriber_id) {
global $mysqli; global $mysqli;
$stmt = $mysqli->prepare("DELETE FROM queue_notify WHERE task_id = ? AND subscriber_id = ?"); $stmt = $mysqli->prepare("DELETE FROM queue_notify WHERE task_id = ? AND subscriber_id = ?");
$stmt->bind_param("ii", $task_id, $subscriber_id); $stmt->bind_param("ii", $task_id, $subscriber_id);
@ -114,7 +114,7 @@ class Queue
} }
// TODO: Fix max attempts for notifications // TODO: Fix max attempts for notifications
public static function process_queue(){ public function process_queue(){
global $mysqli; global $mysqli;
$stmt = $mysqli->query("SELECT qn.id, qn.task_id, qn.status, qn.subscriber_id, qn.retries, sub.firstname, sub.userID, sub.token FROM queue_notify AS qn INNER JOIN subscribers AS sub ON qn.subscriber_id = sub.subscriberID WHERE qn.status NOT LIKE 2 AND sub.active=1"); $stmt = $mysqli->query("SELECT qn.id, qn.task_id, qn.status, qn.subscriber_id, qn.retries, sub.firstname, sub.userID, sub.token FROM queue_notify AS qn INNER JOIN subscribers AS sub ON qn.subscriber_id = sub.subscriberID WHERE qn.status NOT LIKE 2 AND sub.active=1");
while ( $result = $stmt->fetch_assoc() ) { while ( $result = $stmt->fetch_assoc() ) {

View File

@ -1,168 +0,0 @@
<?php
/**
* Class for managing services
*/
class ServiceGroup
{
private $id;
private $name;
private $description;
private $visibility_id;
private $status;
/**
* Constructs servicegroup from its data.
* @param int $id service ID
* @param String $name service name
* @param String $description tooltip text
* @param int $visibility_id how to display group items
*/
function __construct($id, $name, $description, $visibility_id, $status)
{
//TODO: Maybe get data from ID?
$this->id = $id;
$this->name = $name;
$this->description = $description;
$this->visibility_id = $visibility_id;
$this->status = $status;
}
/**
* Returns id of this servicegroup
* @return int id
*/
public function get_id()
{
return $this->id;
}
/**
* Returns name of this servicegroup
* @return String name
*/
public function get_name()
{
return $this->name;
}
/**
* Returns description of this servicegroup
* @return String description
*/
public function get_description()
{
return $this->description;
}
/**
* Processes submitted form and adds service unless problem is encountered,
* calling this is possible only for admin or higher rank. Also checks requirements
* for char limits.
* @return void
*/
public static function add()
{
global $user, $message;
if (strlen($_POST['group'])>50)
{
$message = _("Service group name is too long! Character limit is 50");
return;
}else if (strlen(trim($_POST['group']))==0){
$message = _("Please enter name!");
return;
}
if ($user->get_rank()<=1)
{
global $mysqli;
$name = $_POST["group"];
$description = $_POST["description"];
$visibility_id = $_POST["visibility_id"];
$stmt = $mysqli->prepare("INSERT INTO services_groups VALUES(NULL,?,?,?)");
$stmt->bind_param("ssi", $name, $description, $visibility_id);
$stmt->execute();
$stmt->get_result();
header("Location: ".WEB_URL."/admin/?do=settings");
}else
{
$message = _("You don't have the permission to do that!");
}
}
public static function edit()
{
global $user, $message;
if (strlen($_POST['group'])>50)
{
$message = _("Service group name is too long! Character limit is 50");
return;
}else if (strlen(trim($_POST['group']))==0){
$message = _("Please enter name!");
return;
}
if ($user->get_rank()<=1)
{
global $mysqli;
$name = $_POST["group"];
$description = $_POST["description"];
$visibility_id = $_POST["visibility_id"];
$group_id = $_POST["id"];
$stmt = $mysqli->prepare("UPDATE services_groups SET name=?, description=?,visibility=? WHERE id LIKE ?");
$stmt->bind_param("ssii", $name, $description, $visibility_id, $group_id);
$stmt->execute();
$stmt->get_result();
header("Location: ".WEB_URL."/admin/?do=settings");
}else
{
$message = _("You don't have the permission to do that!");
}
}
/**
* Deletes this service - first checks if user has permission to do that.
* @return void
*/
public static function delete()
{
global $user, $message;
if ($user->get_rank()<=1)
{
global $mysqli;
$id = $_GET['delete'];
$stmt = $mysqli->prepare("DELETE FROM services_groups WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$query = $stmt->get_result();
$stmt = $mysqli->prepare("UPDATE services SET group_id = NULL WHERE group_id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$query = $stmt->get_result();
header("Location: ".WEB_URL."/admin/?do=settings");
}
else
{
$message = _("You don't have the permission to do that!");
}
}
/**
* Get list of services groups.
* @return array $groups
*/
public static function get_groups() {
global $mysqli;
$stmt = $mysqli->query("SELECT id, name FROM services_groups ORDER by name ASC");
$groups = array();
$groups[0] = '';
while ($res = $stmt->fetch_assoc()) {
$groups[$res['id']] = $res['name'];
}
return $groups;
}
}

View File

@ -6,24 +6,19 @@ class Service implements JsonSerializable
{ {
private $id; private $id;
private $name; private $name;
private $description;
private $group_name;
private $status; private $status;
/** /**
* Constructs service from its data. * Constructs service from its data.
* @param int $id service ID * @param int $id service ID
* @param String $name service name * @param String $name service name
* @param String $descriotion service description for tooltip
* @param int $status current service status * @param int $status current service status
*/ */
function __construct($id, $name, $description=null, $group_name='', $status=3) function __construct($id, $name, $status=3)
{ {
//TODO: Maybe get data from ID? //TODO: Maybe get data from ID?
$this->id = $id; $this->id = $id;
$this->name = $name; $this->name = $name;
$this->description = $description;
$this->group_name = $group_name;
$this->status = $status; $this->status = $status;
} }
@ -54,15 +49,6 @@ class Service implements JsonSerializable
return $this->name; return $this->name;
} }
/**
* Returns description of this service
* @return String description
*/
public function get_description()
{
return $this->description;
}
/** /**
* Processes submitted form and adds service unless problem is encountered, * Processes submitted form and adds service unless problem is encountered,
* calling this is possible only for admin or higher rank. Also checks requirements * calling this is possible only for admin or higher rank. Also checks requirements
@ -84,46 +70,9 @@ class Service implements JsonSerializable
if ($user->get_rank()<=1) if ($user->get_rank()<=1)
{ {
global $mysqli; global $mysqli;
$name = htmlspecialchars($_POST['service']); $name = $_POST['service'];
$description = htmlspecialchars($_POST['description']); $stmt = $mysqli->prepare("INSERT INTO services ( name ) VALUES ( ? )");
$group_id = $_POST['group_id']; $stmt->bind_param("s", $name);
$stmt = $mysqli->prepare("INSERT INTO services ( name, description, group_id ) VALUES ( ?, ?, ? )");
$stmt->bind_param("ssi", $name, $description, $group_id);
$stmt->execute();
$stmt->get_result();
header("Location: ".WEB_URL."/admin/?do=settings");
}else
{
$message = _("You don't have the permission to do that!");
}
}
/**
* Processes submitted form and adds service unless problem is encountered,
* calling this is possible only for admin or higher rank. Also checks requirements
* for char limits.
* @return void
*/
public static function edit()
{
global $user, $message;
if (strlen($_POST['service'])>50)
{
$message = _("Service name is too long! Character limit is 50");
return;
}else if (strlen(trim($_POST['service']))==0){
$message = _("Please enter name!");
return;
}
if ($user->get_rank()<=1)
{
global $mysqli;
$service_id = $_POST["id"];
$name = htmlspecialchars($_POST['service']);
$description = htmlspecialchars($_POST["description"]);
$group_id = $_POST["group_id"];
$stmt = $mysqli->prepare("UPDATE services SET name=?, description=?, group_id=? WHERE id = ?");
$stmt->bind_param("ssii", $name, $description, $group_id, $service_id);
$stmt->execute(); $stmt->execute();
$stmt->get_result(); $stmt->get_result();
header("Location: ".WEB_URL."/admin/?do=settings"); header("Location: ".WEB_URL."/admin/?do=settings");
@ -180,7 +129,7 @@ class Service implements JsonSerializable
* @param Service[] $array array of services * @param Service[] $array array of services
* @return void * @return void
*/ */
public static function current_status($array): void{ public static function current_status($array){
global $all, $some, $classes; global $all, $some, $classes;
$statuses = array(0,0,0,0); $statuses = array(0,0,0,0);
$worst = 5; $worst = 5;
@ -206,64 +155,24 @@ class Service implements JsonSerializable
/** /**
* Renders this service. * Renders this service.
* @param $boolGroup set to true if the groups name is to be rendered
* @return void * @return void
*/ */
public function render(){ public function render(){
global $statuses; global $statuses;
global $classes; global $classes;
static $arrCompletedGroups = array(); ?>
//static $boolClosed; <div class="item clearfix">
static $boolOpened; <div class="service"><?php echo $this->name; ?></div>
<?php if ($this->status!=-1){?><div class="status <?php echo $classes[$this->status];?>"><?php echo _($statuses[$this->status]);?></div><?php }?>
// Check if previous ul has been opened, and if a empty/new group is being </div>
// render_header, close the UL first.
if ( $boolOpened ) {
if ( empty($this->group_name) || !in_array($this->group_name, $arrCompletedGroups) ) {
echo '</ul>';
$boolOpened = false;
}
}
// If no group exist or group is new, start a new UL
if ( !empty($this->group_name) && !in_array($this->group_name, $arrCompletedGroups)) {
echo '<ul class="list-group components">';
//echo '<ul class="platforms list-group mb-2">';
// Render the group status if it exists
echo '<li class="list-group-item list-group-item-success group-name"><span><i class="glyphicon glyphicon-plus"></i></span>&nbsp;' . $this->group_name .'<div class="status '. $classes[$this->status] .'">'. _($statuses[$this->status]).'</div></li>';
//echo '<li class="cist-group-item d-flex flex-row justify-content-between platform list-group-item-action py-0 expanded" role="button">' . $this->group_name .'<div class="status '. $classes[$this->status] .'"'. _($statuses[$this->status]).'</div></li>';
$arrCompletedGroups[] = $this->group_name;
$boolOpened = true;
}
if ( empty($this->group_name)) {
echo '<ul class="list-group components">';
// echo '<ul class="platforms list-group mb-2">';
$boolFinish = true;
}
// Render the service status
echo '<li class="list-group-item sub-component"><strong>' . $this->name .'</strong>';
//echo '<li class="list-group-item d-flex flex-columns justify-content-between><span>+</span><h3 class="py-2 my-0 flex-fill expanded">' . $this->name . '</h3>';
if(!empty($this->description)) {
echo '<a class="desc-tool-tip" data-toggle="tooltip" data-placement="top" title="'.$this->description.'"> <span><i class="glyphicon glyphicon-question-sign"></i></span></a>';
}
if ($this->status!=-1){?><div class="status pull-right <?php echo $classes[$this->status];?>"><?php echo _($statuses[$this->status]);?></div>
<?php <?php
} }
echo '</li>';
if ( isset($boolFinish) && $boolFinish) {
echo '</ul>';
}
}
public function jsonSerialize(): mixed { public function jsonSerialize() {
global $statuses; global $statuses;
return [ return [
"id" => $this->id, "id" => $this->id,
"name" => $this->name, "name" => $this->name,
"description" => $this->description,
"status" => $this->status, "status" => $this->status,
"status_string" => $statuses[$this->status] "status_string" => $statuses[$this->status]
]; ];

View File

@ -190,7 +190,7 @@ Class Subscriber
{ {
global $mysqli; global $mysqli;
// error_log(print_r($token, TRUE));
$stmt = $mysqli->prepare("SELECT subscriberID, token, userID, active, expires FROM subscribers WHERE token LIKE ? LIMIT 1"); $stmt = $mysqli->prepare("SELECT subscriberID, token, userID, active, expires FROM subscribers WHERE token LIKE ? LIMIT 1");
$stmt->bind_param("s", $token ); $stmt->bind_param("s", $token );
$stmt->execute(); $stmt->execute();
@ -202,7 +202,7 @@ Class Subscriber
// No data found, fail gently... // No data found, fail gently...
return false; return false;
} }
// error_log(print_r($row, TRUE));
// If account is not already active, check if we are within timeframe of exipre +2h // If account is not already active, check if we are within timeframe of exipre +2h
// and active if so, otherwise,delete account and return falsev // and active if so, otherwise,delete account and return falsev
if ( $row['active'] <> 1 ) { if ( $row['active'] <> 1 ) {

View File

@ -210,12 +210,12 @@ class User
public static function login() public static function login()
{ {
global $message, $mysqli; global $message, $mysqli;
if (!isset($_POST['email']) && !isset($_POST['pass'])) if (!isset($_POST['email']) && !isset($_POST['email']))
{ {
return; return;
} }
if ((!isset($_POST['email']) || !isset($_POST['pass']))) if ((!isset($_POST['email']) || !isset($_POST['email'])))
{ {
$message = _("Please fill in your email and password!"); $message = _("Please fill in your email and password!");
return; return;

View File

@ -7,26 +7,17 @@
// This is needed because some hosts do not either unzip hidden files // This is needed because some hosts do not either unzip hidden files
// or neither GitHub puts that file inside the zips. // or neither GitHub puts that file inside the zips.
/********************************************************************/ /********************************************************************/
$apacheExampleName = "ApacheHtaccess";
$apacheProductionName = ".htaccess";
$iisExampleName = "IISWebConfig";
$iisProductionName = "web.config";
if(stripos($_SERVER['SERVER_SOFTWARE'],'apache')!== false){ if(stripos($_SERVER['SERVER_SOFTWARE'],'apache')!== false){
if(!file_exists($apacheProductionName)) { $f = fopen(".htaccess", "a+");
$f = fopen($apacheProductionName, "a+"); $f2 = fopen("ApacheHtaccess","r");
$f2 = fopen($apacheExampleName,"r"); fwrite($f, fread($f2, filesize("ApacheHtaccess")));
fwrite($f, fread($f2, filesize($apacheExampleName))); fclose($f);
fclose($f); fclose($f2);
fclose($f2);
}
// skipping renaming file if it already exists
} else { } else {
if(!file_exists($iisProductionName)) { $f = fopen("web.config", "a+");
$f = fopen($iisProductionName, "a+"); $f2 = fopen("IISWebConfig","r");
$f2 = fopen($iisExampleName,"r"); fwrite($f, fread($f2, filesize("IISWebConfig")));
fwrite($f, fread($f2, filesize($iisExampleName))); fclose($f);
fclose($f); fclose($f2);
fclose($f2);
}
} }
?> ?>

View File

@ -27,10 +27,6 @@ a:focus {
color:#f5f4f4; color:#f5f4f4;
} }
a.desc-tool-tip, a.desc-tool-tip:hover, a.desc-tool-tip:visited {
color: grey;
}
.centered { .centered {
text-align: center text-align: center
} }
@ -73,6 +69,13 @@ a.desc-tool-tip, a.desc-tool-tip:hover, a.desc-tool-tip:visited {
top: 0; top: 0;
width: 100%; width: 100%;
} }
body {
min-height: 100vh;
height: 100vh;
}
.admins_color h4 { .admins_color h4 {
color: #3a72bd; color: #3a72bd;
font-weight: bold; font-weight: bold;
@ -95,7 +98,7 @@ div.center {
#wrapper #wrapper
{ {
max-width: 1024px; max-width: 1024px;
min-height: calc(100vh - 139px); min-height: calc(100vh - 157px);
padding-right: 15px; padding-right: 15px;
padding-left: 15px padding-left: 15px
} }
@ -133,7 +136,7 @@ body a h1{
.status{ .status{
float: right; float: right;
box-sizing: border-box; box-sizing: border-box;
padding: 0px 35px; padding: 15px 35px;
text-align: right; text-align: right;
font-size: 1.05em; font-size: 1.05em;
font-family: 'Fira Sans', sans-serif; font-family: 'Fira Sans', sans-serif;
@ -683,3 +686,4 @@ input:checked + .slider:before {
.slider.round:before { .slider.round:before {
border-radius: 50%; border-radius: 50%;
} }

View File

@ -1,31 +0,0 @@
version: '3'
networks:
status-db:
services:
server-status:
build: .
volumes:
- ./:/var/www/html
ports:
- 4000:80
networks:
- status-db
dbserver:
image: mysql
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: e347h43cve89
MYSQL_DATABASE: server_status
volumes:
- ./database:/var/lib/mysql
networks:
- status-db
mailhog:
image: mailhog/mailhog
ports:
- "1025:1025"
- "8025:8025"
networks:
- status-db

View File

@ -40,13 +40,14 @@ define("TITLE", $db->getSetting($mysqli,"title"));
define("WEB_URL", $db->getSetting($mysqli,"url")); define("WEB_URL", $db->getSetting($mysqli,"url"));
define("MAILER_NAME", $db->getSetting($mysqli,"mailer")); define("MAILER_NAME", $db->getSetting($mysqli,"mailer"));
define("MAILER_ADDRESS", $db->getSetting($mysqli,"mailer_email")); define("MAILER_ADDRESS", $db->getSetting($mysqli,"mailer_email"));
define("SUBSCRIBE_EMAIL", $db->getBooleanSetting($mysqli,"subscribe_email") ?: "");
define("SUBSCRIBE_TELEGRAM", $db->getBooleanSetting($mysqli,"subscribe_telegram") ?: ""); define("SUBSCRIBE_EMAIL", $db->getBooleanSetting($mysqli,"subscribe_email"));
define("TG_BOT_USERNAME", $db->getSetting($mysqli,"tg_bot_username") ?: ""); define("SUBSCRIBE_TELEGRAM", $db->getBooleanSetting($mysqli,"subscribe_telegram"));
define("TG_BOT_API_TOKEN", $db->getSetting($mysqli,"tg_bot_api_token") ?: ""); define("TG_BOT_USERNAME", $db->getSetting($mysqli,"tg_bot_username"));
define("GOOGLE_RECAPTCHA", $db->getBooleanSetting($mysqli,"google_recaptcha") ?: ""); define("TG_BOT_API_TOKEN", $db->getSetting($mysqli,"tg_bot_api_token"));
define("GOOGLE_RECAPTCHA_SITEKEY", $db->getSetting($mysqli,"google_recaptcha_sitekey") ?: ""); define("GOOGLE_RECAPTCHA", $db->getBooleanSetting($mysqli,"google_recaptcha"));
define("GOOGLE_RECAPTCHA_SECRET", $db->getSetting($mysqli,"google_recaptcha_secret") ?: ""); define("GOOGLE_RECAPTCHA_SITEKEY", $db->getSetting($mysqli,"google_recaptcha_sitekey"));
define("GOOGLE_RECAPTCHA_SECRET", $db->getSetting($mysqli,"google_recaptcha_secret"));
$offset = 0; $offset = 0;
if (isset($_GET['ajax'])) if (isset($_GET['ajax']))
@ -67,7 +68,6 @@ if (isset($_GET['subscriber_logout'])){
unset($_SESSION['subscriber_id']); unset($_SESSION['subscriber_id']);
header('Location: index.php'); header('Location: index.php');
} }
/*
$versionfile = fopen("versionfile", "r") or die("Unable to open version file!"); $versionfile = fopen("versionfile", "r") or die("Unable to open version file!");
$appversion = fread($versionfile,filesize("versionfile")); $appversion = fread($versionfile,filesize("versionfile"));
fclose($versionfile); fclose($versionfile);
@ -90,7 +90,6 @@ if($db->getSetting($mysqli,"notifyUpdates") == "yes"){
die("Your installation is not upp to date! Download the new update from: '".$remotedl."' Your version is:'".$appversion."' Remote Authority Version is:'".$remoteversion."' Your Update Seed is:'".$useed."' Remote Package Authority is Skyfallen. <br>If you cannot access Remote Authority, please check status.theskyfallen.com and skyfallenhosted.ml manually."); die("Your installation is not upp to date! Download the new update from: '".$remotedl."' Your version is:'".$appversion."' Remote Authority Version is:'".$remoteversion."' Your Update Seed is:'".$useed."' Remote Package Authority is Skyfallen. <br>If you cannot access Remote Authority, please check status.theskyfallen.com and skyfallenhosted.ml manually.");
} }
} }
*/
Template::render_header("Status"); Template::render_header("Status");
?> ?>
<div class="text-center"> <div class="text-center">
@ -100,7 +99,7 @@ Template::render_header("Status");
<?php $constellation->render_status();?> <?php $constellation->render_status();?>
</div> </div>
<?php if ($mysqli->query("SELECT count(*) FROM status")) <?php if ($mysqli->query("SELECT count(*) FROM status")->num_rows)
{ {
?> ?>
<div id="timeline"> <div id="timeline">
@ -118,10 +117,3 @@ Template::render_header("Status");
Template::render_footer(); Template::render_footer();
} }
?>
<script>
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
</script>
<?php

View File

@ -9,14 +9,6 @@ define("COPYRIGHT_TEXT","");
require_once("classes/locale-negotiator.php"); require_once("classes/locale-negotiator.php");
require_once("classes/db-class.php"); require_once("classes/db-class.php");
$isDeveleoperEnvironement = false;
if(isset($_GET["isDev"])){
if($_GET["isDev"] == "devMode"){
$isDeveleoperEnvironement = true;
}
}
$negotiator = new LocaleNegotiator("en_GB"); $negotiator = new LocaleNegotiator("en_GB");
$message = ""; $message = "";
$db = new SSDB(); $db = new SSDB();
@ -169,12 +161,11 @@ if(isset($_POST['server']) && empty($message))
$db->setSetting($mysqli,"google_recaptcha_secret",""); $db->setSetting($mysqli,"google_recaptcha_secret","");
$db->setSetting($mysqli,"google_recaptcha_sitekey",""); $db->setSetting($mysqli,"google_recaptcha_sitekey","");
$db->setSetting($mysqli,"cron_server_ip",""); $db->setSetting($mysqli,"cron_server_ip","");
if(!$isDeveleoperEnvironement) {
unlink("create-server-config.php"); unlink("create-server-config.php");
unlink("config.php.template"); unlink("config.php.template");
unlink("install.sql"); unlink("install.sql");
unlink(__FILE__); unlink(__FILE__);
}
header("Location: ".WEB_URL); header("Location: ".WEB_URL);
} }
} }

View File

@ -57,14 +57,6 @@ CREATE TABLE queue_notify (
PRIMARY KEY (id) PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;
CREATE TABLE services_groups (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
description varchar(50) DEFAULT NULL,
visibility tinyint(4) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE queue_task ( CREATE TABLE queue_task (
id int(11) NOT NULL AUTO_INCREMENT, id int(11) NOT NULL AUTO_INCREMENT,
type_id int(11) NOT NULL, type_id int(11) NOT NULL,
@ -136,7 +128,3 @@ ALTER TABLE `subscribers` ADD COLUMN update_time int(11) DEFAULT NULL;
ALTER TABLE `subscribers` DROP INDEX telegramID; # was UNIQUE (telegramID) ALTER TABLE `subscribers` DROP INDEX telegramID; # was UNIQUE (telegramID)
ALTER TABLE `subscribers` ADD UNIQUE userID (userID); ALTER TABLE `subscribers` ADD UNIQUE userID (userID);
COMMIT; COMMIT;
ALTER TABLE services ADD COLUMN description varchar(200) COLLATE utf8_czech_ci NOT NULL;
ALTER TABLE services ADD COLUMN group_id int(11) DEFAULT NULL;
COMMIT;

View File

@ -12,7 +12,7 @@ function ordUTF8($c, $index = 0, &$bytes = null)
$bytes = 0; $bytes = 0;
if ($index >= $len) if ($index >= $len)
return false; return false;
$h = ord($c[$index]); $h = ord($c{$index});
if ($h <= 0x7F) { if ($h <= 0x7F) {
$bytes = 1; $bytes = 1;
return $h; return $h;
@ -21,18 +21,18 @@ function ordUTF8($c, $index = 0, &$bytes = null)
return false; return false;
else if ($h <= 0xDF && $index < $len - 1) { else if ($h <= 0xDF && $index < $len - 1) {
$bytes = 2; $bytes = 2;
return ($h & 0x1F) << 6 | (ord($c[$index + 1]) & 0x3F); return ($h & 0x1F) << 6 | (ord($c{$index + 1}) & 0x3F);
} }
else if ($h <= 0xEF && $index < $len - 2) { else if ($h <= 0xEF && $index < $len - 2) {
$bytes = 3; $bytes = 3;
return ($h & 0x0F) << 12 | (ord($c[$index + 1]) & 0x3F) << 6 return ($h & 0x0F) << 12 | (ord($c{$index + 1}) & 0x3F) << 6
| (ord($c[$index + 2]) & 0x3F); | (ord($c{$index + 2}) & 0x3F);
} }
else if ($h <= 0xF4 && $index < $len - 3) { else if ($h <= 0xF4 && $index < $len - 3) {
$bytes = 4; $bytes = 4;
return ($h & 0x0F) << 18 | (ord($c[$index + 1]) & 0x3F) << 12 return ($h & 0x0F) << 18 | (ord($c{$index + 1}) & 0x3F) << 12
| (ord($c[$index + 2]) & 0x3F) << 6 | (ord($c{$index + 2}) & 0x3F) << 6
| (ord($c[$index + 3]) & 0x3F); | (ord($c{$index + 3}) & 0x3F);
} }
else else
return false; return false;

View File

@ -52,5 +52,5 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p style="text-align: center;"><a href="%url%/?do=unsubscribe&amp;type=2&amp;token=%token%"><sub><sup>%unsubscribe%</sup></sub></a></p> <p style="text-align: center;"><a href="%url%/?do=unsubscribe&amp;token=%token%"><sub><sup>%unsubscribe%</sup></sub></a></p>
<p style="text-align: center;"><a href="%url%"><img src="%url%/favicon/apple-icon-57x57.png" alt="" />&nbsp;%powered_by%&nbsp;Server-Status</a></p> <p style="text-align: center;"><a href="%url%"><img src="%url%/favicon/apple-icon-57x57.png" alt="" />&nbsp;%powered_by%&nbsp;Server-Status</a></p>

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,12 @@
<?php <?php
//This should later be translatable, maybe find a better solution?
// enable this for debugging //This is here for better generation of POT files :)
// error_reporting(E_ALL);
// ini_set('display_startup_errors', 1);
// ini_set('display_errors', 1);
// ini_set("log_errors", 1);
$statuses = array(_("Major outage"), _("Minor outage"), _("Planned maintenance"), _("Operational") ); $statuses = array(_("Major outage"), _("Minor outage"), _("Planned maintenance"), _("Operational") );
$classes = array("danger", "warning", "primary", "success" ); $classes = array("danger", "warning", "primary", "success" );
$icons = array("fa fa-times", "fa fa-exclamation", "fa fa-info", "fa fa-check" ); $icons = array("fa fa-times", "fa fa-exclamation", "fa fa-info", "fa fa-check" );
$some = array(_("Some systems are experiencing major outages"), _("Some systems are experiencing minor outages"), _("Some systems are under maintenance")); $some = array(_("Some systems are experiencing major outages"), _("Some systems are experiencing minor outages"), _("Some systems are under maintenance"));
$all = array(_("Our systems are experiencing major outages."), _("Our systems are experiencing minor outages"), _("Our systems are under maintenance"), _("All systems operational")); $all = array(_("Our systems are experiencing major outages."), _("Our systems are experiencing minor outages"), _("Our systems are under maintenance"), _("All systems operational"));
$permissions = array(_("Super admin"), _("Admin"), _("Editor")); $permissions = array(_("Super admin"), _("Admin"), _("Editor"));
$visibility = array(_("Collapsed"), _("Expanded"), _("Expand on events"));
/** /**
* Class that encapsulates methods to render header and footer * Class that encapsulates methods to render header and footer
@ -33,8 +27,7 @@ class Template{
if ( 'admin' == $str_url ) { if ( 'admin' == $str_url ) {
$strSubsMenu = ''; $strSubsMenu = '';
} else { } else {
$strSubsMenu = ''; if (SUBSCRIBE_EMAIL || SUBSCRIBE_TELEGRAM ) {
if (defined('SUBSCRIBE_EMAIL') || defined('SUBSCRIBE_TELEGRAM') ) {
// Subscriber menu is to be shown... // Subscriber menu is to be shown...
$strSubsMenu = '<ul class="nav navbar-nav mr-auto">'; $strSubsMenu = '<ul class="nav navbar-nav mr-auto">';
// If subscriber is not logged on, display subscriber menus // If subscriber is not logged on, display subscriber menus
@ -64,13 +57,9 @@ class Template{
<html lang="en"> <html lang="en">
<head> <head>
<?php <?php
if(defined('admin') && !admin){
$headfile = fopen("head.txt", "r") or die("Unable to open head.txt!"); $headfile = fopen("head.txt", "r") or die("Unable to open head.txt!");
$head_additionalcode = fread($versionfile ?? "Version2Beta8",filesize("head.txt")); $head_additionalcode = fread($versionfile,filesize("head.txt"));
fclose($headfile); fclose($headfile); ?>
echo $head_additionalcode;
}
?>
<meta charset="utf-8"> <meta charset="utf-8">
<title><?php echo $page_name." - ".NAME ?></title> <title><?php echo $page_name." - ".NAME ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
@ -184,9 +173,6 @@ class Template{
/** /**
* Renders a toggle switch * Renders a toggle switch
* Created by Yigit Kerem Oktay * Created by Yigit Kerem Oktay
* @param String $toggletext will decide what the description text next to the toggle will be
* @param String $input_name will decide what the HTML Name attribute of the toggle will be
* @param Boolean $checked will decide if the toggle will initially be on or off
*/ */
public static function render_toggle($toggletext,$input_name,$checked){ public static function render_toggle($toggletext,$input_name,$checked){
?> ?>
@ -212,7 +198,7 @@ class Template{
<div id="footerwrap"> <div id="footerwrap">
<div class="container"> <div class="container">
<div class="row centered"> <div class="row centered">
<div class="col-md-4 text-left"><a href="https://github.com/server-status-project/server-status/graphs/contributors" target="_blank">Copyright © <?php echo date("Y");?> Server Status Project Contributors </a><?php if(strlen(COPYRIGHT_TEXT)>1){ echo " and ".COPYRIGHT_TEXT; } ?></div> <div class="col-md-4 text-left"><a href="https://github.com/Pryx/server-status/graphs/contributors" target="_blank">Copyright © <?php echo date("Y");?> Server Status Project Contributors </a><?php if(strlen(COPYRIGHT_TEXT)>1){ echo " and ".COPYRIGHT_TEXT; } ?></div>
<div class="col-md-4 text-center"> <div class="col-md-4 text-center">
<div class="btn-group dropup"> <div class="btn-group dropup">
<button type="button" class="btn btn-primary"><?php echo '<img src="'.WEB_URL.'/locale/'.$_SESSION['locale'].'/flag.png" alt="'.$lang_names[$_SESSION['locale']].'">'.$lang_names[$_SESSION['locale']];?></button> <button type="button" class="btn btn-primary"><?php echo '<img src="'.WEB_URL.'/locale/'.$_SESSION['locale'].'/flag.png" alt="'.$lang_names[$_SESSION['locale']].'">'.$lang_names[$_SESSION['locale']];?></button>
@ -245,7 +231,7 @@ class Template{
<?php }?> <?php }?>
<script src="<?php echo WEB_URL;?>/js/vendor/bootstrap.min.js"></script> <script src="<?php echo WEB_URL;?>/js/vendor/bootstrap.min.js"></script>
<script src="<?php echo WEB_URL;?>/js/main.js"></script> <script src="<?php echo WEB_URL;?>/js/main.js"></script>
<?php if ( defined('GOOGLE_RECAPTCHA') ) { ?><script src='https://www.google.com/recaptcha/api.js'></script><?php }?> <?php if ( GOOGLE_RECAPTCHA ) { ?><script src='https://www.google.com/recaptcha/api.js'></script><?php }?>
</body> </body>
</html> </html>
<?php <?php

View File

@ -1 +1 @@
Version2Beta8 Version2Beta7