Skip to content
This repository has been archived by the owner on Dec 9, 2023. It is now read-only.

Commit

Permalink
First commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
seikan committed Dec 12, 2016
1 parent 8bb2ef4 commit c22610c
Show file tree
Hide file tree
Showing 33 changed files with 2,610 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .htaccess.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Options -Indexes
RewriteEngine On

RewriteRule ^(.+)\.json$ index.php?q=json.$1.php [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?page=$1 [L,QSA]
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# NodeList

This is a small web application I wrote to keep track all my VPS and dedicated servers. The codes may messy as it was using by myself only in last 3 years.

The codes are written in PHP and frontend with [Bootstrap](http://getbootstrap.com/). The database is stored in CSV files with no MySQL or SQLite extension needed.

I just added a `setup.php` so everyone can try to install and run it.

I will continue update the application if needed.
Empty file added configuration.php.new
Empty file.
1 change: 1 addition & 0 deletions databases/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Access denied.
Binary file added images/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions includes/css/bootstrap.min.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions includes/css/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Access denied.
19 changes: 19 additions & 0 deletions includes/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
body{padding-top:80px;padding-bottom:100px}
@media (min-width:768px) {
body>.navbar-transparent{background-color:transparent}
body>.navbar-transparent .navbar-nav>.open>a{background-color:transparent!important}
}
.navbar-brand{padding:5px;margin-right:30px;font-size:15px}
.input-group-btn:last-child > .btn-group,.input-group .input-group-btn{z-index:auto}
.table > tbody > tr > td,.table > tbody > tr > th{position:relative;vertical-align:middle;white-space:nowrap}
textarea{resize:none}
input[type="text"],input[type="email"],input[type="search"],input[type="password"],input[type="number"],textarea{-webkit-appearance:none;-webkit-box-shadow:none !important;-moz-box-shadow:none !important;box-shadow:none !important}
.location{margin:10px 0;font-size:11px}
.control-panel{margin:10px 0}
.machine-name,.machine-ip{cursor:pointer}
.machine-ip .fa{visibility:hidden}
.machine-ip:hover .fa{visibility:visible}
.label-hdd{font-size:10px;display:block}
.full-width{width:100%}
.swap{font-size:10px;color:#777}
.nat{font-size:6px;position:absolute;top:6px}
47 changes: 47 additions & 0 deletions includes/error-handler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
set_exception_handler('exceptionHandler');

set_error_handler(function($number, $message, $file, $line){
exceptionHandler(new ErrorException($message, $number, 0, $file, $line));
});

register_shutdown_function(function(){
if($error = error_get_last())
exceptionHandler(new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']));
});

function exceptionHandler($e){
if(error_reporting() == 0)
return;

file_put_contents(LOGS . 'error-' . date('Ymd') . '_' . md5(microtime()) . '.log', implode("\n", array(
'Date :' . date('Y-m-d H:i:s'),
'Error : ' . $e->getMessage(),
'File : ' . $e->getFile() . ': ' . $e->getLine(),
'URL : ' . ((isset($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : ''),
)));

switch($e->getCode()){
case E_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_CORE_WARNING:
case E_COMPILE_ERROR:
case E_COMPILE_WARNING:
case E_USER_ERROR:
die('<html><head><title>Internal Server Error</title></head><body><h2>Internal Server Error</h2><p>An unexpected error has occurred.</p></body></html>');

case E_WARNING:
case E_NOTICE:
case E_USER_WARNING:
case E_USER_NOTICE:
case E_STRICT:
case E_RECOVERABLE_ERROR:
case E_DEPRECATED:
case E_USER_DEPRECATED:
default:

break;
}
}
?>
25 changes: 25 additions & 0 deletions includes/footer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script src="//code.jquery.com/jquery-3.1.0.min.js" type="text/javascript"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js" type="text/javascript"></script>

<?php
if(isset($js) && is_array($js))
echo "\t\t<script src=\"" . implode("\" type=\"text/javascript\"></script>\n\t\t<script src=\"", $js) . "\" type=\"text/javascript\"></script>\n\n";

if(isset($scripts)){
echo "\t\t" . implode("\n\t\t", array(
'<script>',
'<!--',
trim($scripts),
'//-->',
'</script>',
)) . "\n\n";
}
?>

<script>
setInterval(function(){
$.post('<?php echo getURL('refresh-session.json'); ?>');
}, 300000);
</script>
</body>
</html>
50 changes: 50 additions & 0 deletions includes/functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
$countries = array('AF' => 'Afghanistan', 'AX' => 'Åland Islands', 'AL' => 'Albania', 'DZ' => 'Algeria', 'AS' => 'American Samoa', 'AD' => 'Andorra', 'AO' => 'Angola', 'AI' => 'Anguilla', 'AQ' => 'Antarctica', 'AG' => 'Antigua and Barbuda', 'AR' => 'Argentina', 'AM' => 'Armenia', 'AW' => 'Aruba', 'AU' => 'Australia', 'AT' => 'Austria', 'AZ' => 'Azerbaijan', 'BS' => 'Bahamas', 'BH' => 'Bahrain', 'BD' => 'Bangladesh', 'BB' => 'Barbados', 'BY' => 'Belarus', 'BE' => 'Belgium', 'BZ' => 'Belize', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BT' => 'Bhutan', 'BO' => 'Bolivia, Plurinational State of', 'BQ' => 'Bonaire, Sint Eustatius and Saba', 'BA' => 'Bosnia and Herzegovina', 'BW' => 'Botswana', 'BV' => 'Bouvet Island', 'BR' => 'Brazil', 'IO' => 'British Indian Ocean Territory', 'BN' => 'Brunei Darussalam', 'BG' => 'Bulgaria', 'BF' => 'Burkina Faso', 'BI' => 'Burundi', 'KH' => 'Cambodia', 'CM' => 'Cameroon', 'CA' => 'Canada', 'CV' => 'Cape Verde', 'KY' => 'Cayman Islands', 'CF' => 'Central African Republic', 'TD' => 'Chad', 'CL' => 'Chile', 'CN' => 'China', 'CX' => 'Christmas Island', 'CC' => 'Cocos (Keeling) Islands', 'CO' => 'Colombia', 'KM' => 'Comoros', 'CG' => 'Congo', 'CD' => 'Congo, the Democratic Republic of the', 'CK' => 'Cook Islands', 'CR' => 'Costa Rica', 'CI' => 'Côte d\'Ivoire', 'HR' => 'Croatia', 'CU' => 'Cuba', 'CW' => 'Curaçao', 'CY' => 'Cyprus', 'CZ' => 'Czech Republic', 'DK' => 'Denmark', 'DJ' => 'Djibouti', 'DM' => 'Dominica', 'DO' => 'Dominican Republic', 'EC' => 'Ecuador', 'EG' => 'Egypt', 'SV' => 'El Salvador', 'GQ' => 'Equatorial Guinea', 'ER' => 'Eritrea', 'EE' => 'Estonia', 'ET' => 'Ethiopia', 'FK' => 'Falkland Islands (Malvinas)', 'FO' => 'Faroe Islands', 'FJ' => 'Fiji', 'FI' => 'Finland', 'FR' => 'France', 'GF' => 'French Guiana', 'PF' => 'French Polynesia', 'TF' => 'French Southern Territories', 'GA' => 'Gabon', 'GM' => 'Gambia', 'GE' => 'Georgia', 'DE' => 'Germany', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GR' => 'Greece', 'GL' => 'Greenland', 'GD' => 'Grenada', 'GP' => 'Guadeloupe', 'GU' => 'Guam', 'GT' => 'Guatemala', 'GG' => 'Guernsey', 'GN' => 'Guinea', 'GW' => 'Guinea-Bissau', 'GY' => 'Guyana', 'HT' => 'Haiti', 'HM' => 'Heard Island and McDonald Islands', 'VA' => 'Holy See (Vatican City State)', 'HN' => 'Honduras', 'HK' => 'Hong Kong', 'HU' => 'Hungary', 'IS' => 'Iceland', 'IN' => 'India', 'ID' => 'Indonesia', 'IR' => 'Iran, Islamic Republic of', 'IQ' => 'Iraq', 'IE' => 'Ireland', 'IM' => 'Isle of Man', 'IL' => 'Israel', 'IT' => 'Italy', 'JM' => 'Jamaica', 'JP' => 'Japan', 'JE' => 'Jersey', 'JO' => 'Jordan', 'KZ' => 'Kazakhstan', 'KE' => 'Kenya', 'KI' => 'Kiribati', 'KP' => 'Korea, Democratic People\'s Republic of', 'KR' => 'Korea, Republic of', 'KW' => 'Kuwait', 'KG' => 'Kyrgyzstan', 'LA' => 'Lao People\'s Democratic Republic', 'LV' => 'Latvia', 'LB' => 'Lebanon', 'LS' => 'Lesotho', 'LR' => 'Liberia', 'LY' => 'Libya', 'LI' => 'Liechtenstein', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'MO' => 'Macao', 'MK' => 'Macedonia, the Former Yugoslav Republic of', 'MG' => 'Madagascar', 'MW' => 'Malawi', 'MY' => 'Malaysia', 'MV' => 'Maldives', 'ML' => 'Mali', 'MT' => 'Malta', 'MH' => 'Marshall Islands', 'MQ' => 'Martinique', 'MR' => 'Mauritania', 'MU' => 'Mauritius', 'YT' => 'Mayotte', 'MX' => 'Mexico', 'FM' => 'Micronesia, Federated States of', 'MD' => 'Moldova, Republic of', 'MC' => 'Monaco', 'MN' => 'Mongolia', 'ME' => 'Montenegro', 'MS' => 'Montserrat', 'MA' => 'Morocco', 'MZ' => 'Mozambique', 'MM' => 'Myanmar', 'NA' => 'Namibia', 'NR' => 'Nauru', 'NP' => 'Nepal', 'NL' => 'Netherlands', 'NC' => 'New Caledonia', 'NZ' => 'New Zealand', 'NI' => 'Nicaragua', 'NE' => 'Niger', 'NG' => 'Nigeria', 'NU' => 'Niue', 'NF' => 'Norfolk Island', 'MP' => 'Northern Mariana Islands', 'NO' => 'Norway', 'OM' => 'Oman', 'PK' => 'Pakistan', 'PW' => 'Palau', 'PS' => 'Palestine, State of', 'PA' => 'Panama', 'PG' => 'Papua New Guinea', 'PY' => 'Paraguay', 'PE' => 'Peru', 'PH' => 'Philippines', 'PN' => 'Pitcairn', 'PL' => 'Poland', 'PT' => 'Portugal', 'PR' => 'Puerto Rico', 'QA' => 'Qatar', 'RE' => 'Réunion', 'RO' => 'Romania', 'RU' => 'Russian Federation', 'RW' => 'Rwanda', 'BL' => 'Saint Barthélemy', 'SH' => 'Saint Helena, Ascension and Tristan da Cunha', 'KN' => 'Saint Kitts and Nevis', 'LC' => 'Saint Lucia', 'MF' => 'Saint Martin (French part)', 'PM' => 'Saint Pierre and Miquelon', 'VC' => 'Saint Vincent and the Grenadines', 'WS' => 'Samoa', 'SM' => 'San Marino', 'ST' => 'Sao Tome and Principe', 'SA' => 'Saudi Arabia', 'SN' => 'Senegal', 'RS' => 'Serbia', 'SC' => 'Seychelles', 'SL' => 'Sierra Leone', 'SG' => 'Singapore', 'SX' => 'Sint Maarten (Dutch part)', 'SK' => 'Slovakia', 'SI' => 'Slovenia', 'SB' => 'Solomon Islands', 'SO' => 'Somalia', 'ZA' => 'South Africa', 'GS' => 'South Georgia and the South Sandwich Islands', 'SS' => 'South Sudan', 'ES' => 'Spain', 'LK' => 'Sri Lanka', 'SD' => 'Sudan', 'SR' => 'Suriname', 'SJ' => 'Svalbard and Jan Mayen', 'SZ' => 'Swaziland', 'SE' => 'Sweden', 'CH' => 'Switzerland', 'SY' => 'Syrian Arab Republic', 'TW' => 'Taiwan, Province of China', 'TJ' => 'Tajikistan', 'TZ' => 'Tanzania, United Republic of', 'TH' => 'Thailand', 'TL' => 'Timor-Leste', 'TG' => 'Togo', 'TK' => 'Tokelau', 'TO' => 'Tonga', 'TT' => 'Trinidad and Tobago', 'TN' => 'Tunisia', 'TR' => 'Turkey', 'TM' => 'Turkmenistan', 'TC' => 'Turks and Caicos Islands', 'TV' => 'Tuvalu', 'UG' => 'Uganda', 'UA' => 'Ukraine', 'AE' => 'United Arab Emirates', 'GB' => 'United Kingdom', 'US' => 'United States', 'UM' => 'United States Minor Outlying Islands', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VU' => 'Vanuatu', 'VE' => 'Venezuela, Bolivarian Republic of', 'VN' => 'Viet Nam', 'VG' => 'Virgin Islands, British', 'VI' => 'Virgin Islands, U.S.', 'WF' => 'Wallis and Futuna', 'EH' => 'Western Sahara', 'YE' => 'Yemen', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe');

function getCountryNameByCode($code){
global $countries;

return (isset($countries[$code])) ? $countries[$code] : FALSE;
}

// Remove slashes
function strips($s){
if(!is_array($s) && !is_object($s))
return htmlentities(strip_tags(stripslashes(trim($s))));

foreach($s as $key=>$value)
(is_array($s)) ? $s[$key] = strips($value) : $s->{$key} = strips($value);

return $s;
}

// Generate random string
function randomCode($length = 16){
$pattern = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

$key = '';
for($i=0; $i<$length; $i++)
$key .= $pattern{mt_rand(0, strlen($pattern)-1)};

return $key;
}

// Get URL of current page
function getPageURL(){
$s = empty($_SERVER['HTTPS']) ? '' : ($_SERVER['HTTPS'] == 'on') ? 's' : '';
$protocol = substr(strtolower($_SERVER['SERVER_PROTOCOL']), 0, strpos(strtolower($_SERVER['SERVER_PROTOCOL']), '/')) . $s;
$port = ($_SERVER['SERVER_PORT'] == '80') ? '' : (':' . $_SERVER['SERVER_PORT']);
return $protocol . '://' . $_SERVER['SERVER_NAME'] . $port . $_SERVER['REQUEST_URI'];
}

// Get working URL
function getURL($page, $queries = array()){
if(substr($page, -5) == '.json')
$page = 'json.' . substr($page, 0, -5);

if(defined('URL_REWRITE'))
return './' . $page . ((!empty($queries)) ? '?' . http_build_query($queries) : '');

return './?page=' . $page . ((!empty($queries)) ? '&' . http_build_query($queries) : '');
}
?>
72 changes: 72 additions & 0 deletions includes/header.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Node List</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="format-detection" content="telephone=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge">

<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="./includes/css/style.css">

<link rel="apple-touch-icon" href="./images/icon.png" />

<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->

<?php
if(isset($css) && is_array($css))
echo "<link href=\"" . implode("\" rel=\"stylesheet\" type=\"text/css\" media=\"screen\" />\n\t\t<link href=\"", $css) . "\" rel=\"stylesheet\" type=\"text/css\" media=\"screen\" />\n\n";

if(isset($styles)){
echo "\t\t" . implode("\n\t\t", array(
'<style type="text/css">',
'<!--',
"\t" . $styles,
'//-->',
'</style>',
)) . "\n\n";
}
?>
</head>

<body>
<div class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a href="./" class="navbar-brand">
<span class="fa-stack fa-lg">
<i class="fa fa-circle fa-stack-2x"></i>
<i class="fa fa-rocket fa-stack-1x fa-inverse"></i>
</span>
</a>

<button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#navbar-main">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>

<div class="navbar-collapse collapse" id="navbar-main">
<ul class="nav navbar-nav">
<li<?php if($_PAGE == 'machine') echo ' class="active"'; ?>><a href="<?php echo getURL('machine'); ?>">Machines</a></li>
<li<?php if($_PAGE == 'provider') echo ' class="active"'; ?>><a href="<?php echo getURL('provider'); ?>">Providers</a></li>
</ul>

<?php
if($session->get('username'))
echo '
<ul class="nav navbar-nav navbar-right">
<li><a href="' . getURL('sign-in', array(
'action' => 'sign-out'
)) . '"><i class="fa fa-sign-out"></i> Sign Out</a></li>
</ul>';
?>
</div>
</div>
</div>
1 change: 1 addition & 0 deletions includes/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Access denied.
78 changes: 78 additions & 0 deletions index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
// Preset PHP settings
error_reporting(E_ALL);
ini_set('display_errors', 0);
date_default_timezone_set('UTC');

// Define this as parent file
define('INDEX', 1);

// Define root directory
define('DS', DIRECTORY_SEPARATOR);
define('ROOT', dirname(__FILE__) . DS);

// Define folders directory
define('DATABASES', ROOT . 'databases' . DS);
define('INCLUDES', ROOT . 'includes' . DS);
define('LIBRARIES', ROOT . 'libraries' . DS);
define('LOGS', ROOT . 'logs' . DS);
define('PAGES', ROOT . 'pages' . DS);

if(!file_exists(ROOT . 'configuration.php'))
die('PLEASE CREATE AN EMPTY FILE "configuration.php".');

// Configuration
require_once ROOT . 'configuration.php';

if(!isset($config) && file_exists(ROOT . 'setup.php'))
die(header('Location: setup.php'));

if(isset($config) && file_exists(ROOT . 'setup.php'))
die('PLEASE DELETE "setup.php" TO CONTINUE.');

// Add error handler
require_once INCLUDES . 'error-handler.php';

// Common functions
require_once INCLUDES . 'functions.php';

// Session
require_once LIBRARIES . 'class.Session.php';
$session = new Session();

// Clean up GET and POST requests to prevent XSS
$_GET = strips($_GET);

// Convert POST into SESSION for Post/Redirect/Get pattern (PRG)
if(!empty($_POST)){
$session->set('_POST', strips($_POST));
die(header('Location: ' . getPageURL()));
}

if($session->get('_POST')){
$_POST = $session->get('_POST');
$session->set('_POST', NULL);
}

// Database
require_once LIBRARIES . 'class.SimpleDB.php';

// Get requested page
$_PAGE = (isset($_GET['page'])) ? $_GET['page'] : 'machine';

// Validate pages to prevent file inclusion vulnerability
$pages = array();

if($handle = opendir(PAGES)){
while(($entry = readdir($handle)) !== FALSE){
if(substr($entry, -4) != '.php')
continue;

$pages[str_replace('.php', '', $entry)] = TRUE;
}
closedir($handle);
}

// Display requested page
require_once PAGES . ((isset($pages[$_PAGE])) ? $_PAGE : '404') . '.php';
?>
36 changes: 36 additions & 0 deletions libraries/class.Session.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
class Session {
protected $session, $id;

public function __construct($id = NULL) {
if(!session_id())
session_start();

$this->id = ($id) ? $id : md5($_SERVER['HTTP_HOST'] . '_session');

if(isset($_SESSION[$this->id]) && is_null($this->session = json_decode($_SESSION[$this->id], TRUE)) === FALSE)
return;

$_SESSION[$this->id] = json_encode(array(''=>''));
$this->session = json_decode($_SESSION[$this->id], TRUE);
}

public function get($key) {
return (isset($this->session[$key])) ? $this->session[$key] : NULL;
}

public function set($key, $value = NULL) {
$this->session[$key] = $value;

if(is_null($value))
unset($this->session[$key]);

$_SESSION[$this->id] = json_encode($this->session);
}

public function destroy() {
unset($_SESSION[$this->id]);
$this->session = NULL;
}
}
?>
Loading

0 comments on commit c22610c

Please sign in to comment.