update api and ajax handling and response

This commit is contained in:
envoyr
2022-02-20 11:38:08 +01:00
parent d5e53cc7db
commit 424a00b39e
65 changed files with 881 additions and 2736 deletions

View File

@@ -1,5 +1,5 @@
[![Froxlor-CI](https://github.com/Froxlor/Froxlor/actions/workflows/build-mariadb.yml/badge.svg?branch=master)](https://github.com/Froxlor/Froxlor/actions/workflows/build-mariadb.yml)
[![Froxlor-CI](https://github.com/Froxlor/Froxlor/actions/workflows/build-mysql.yml/badge.svg?branch=master)](https://github.com/Froxlor/Froxlor/actions/workflows/build-mysql.yml)
[![Froxlor-CI](https://github.com/Froxlor/Froxlor/actions/workflows/build-mariadb.yml/badge.svg?branch=0.11-dev)](https://github.com/Froxlor/Froxlor/actions/workflows/build-mariadb.yml)
[![Froxlor-CI](https://github.com/Froxlor/Froxlor/actions/workflows/build-mysql.yml/badge.svg?branch=0.11-dev)](https://github.com/Froxlor/Froxlor/actions/workflows/build-mysql.yml)
[![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.froxlor.org)
# Froxlor

View File

@@ -211,10 +211,10 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') {
$admin_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/admin/formfield.admin_add.php';
UI::TwigBuffer('user/form.html.twig', [
UI::twigBuffer('user/form.html.twig', [
'formdata' => $admin_add_data['admin_add']
]);
UI::TwigOutputBuffer();
UI::twigOutputBuffer();
}
} elseif ($action == 'edit' && $id != 0) {
try {
@@ -258,10 +258,10 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') {
$admin_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/admin/formfield.admin_edit.php';
UI::TwigBuffer('user/form.html.twig', [
UI::twigBuffer('user/form.html.twig', [
'formdata' => $admin_edit_data['admin_edit']
]);
UI::TwigOutputBuffer();
UI::twigOutputBuffer();
}
}
}

View File

@@ -321,10 +321,10 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
$customer_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/customer/formfield.customer_add.php';
UI::TwigBuffer('user/form.html.twig', [
UI::twigBuffer('user/form.html.twig', [
'formdata' => $customer_add_data['customer_add']
]);
UI::TwigOutputBuffer();
UI::twigOutputBuffer();
}
} elseif ($action == 'edit' && $id != 0) {
@@ -406,10 +406,10 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
$customer_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/customer/formfield.customer_edit.php';
UI::TwigBuffer('user/form.html.twig', [
UI::twigBuffer('user/form.html.twig', [
'formdata' => $customer_edit_data['customer_edit']
]);
UI::TwigOutputBuffer();
UI::twigOutputBuffer();
}
}
}

View File

@@ -180,14 +180,14 @@ if ($page == 'overview') {
'uptime' => $uptime
];
UI::Twig()->addGlobal('userinfo', $userinfo);
UI::TwigBuffer('user/index.html.twig', [
UI::twig()->addGlobal('userinfo', $userinfo);
UI::twigBuffer('user/index.html.twig', [
'sysinfo' => $sysinfo,
'overview' => $overview,
'outstanding_tasks' => $outstanding_tasks,
'cron_last_runs' => $cron_last_runs
]);
UI::TwigOutputBuffer();
UI::twigOutputBuffer();
} elseif ($page == 'change_password') {
if (isset($_POST['send']) && $_POST['send'] == 'send') {
@@ -236,8 +236,8 @@ if ($page == 'overview') {
));
}
} else {
UI::TwigBuffer('user/change_password.html.twig');
UI::TwigOutputBuffer();
UI::twigBuffer('user/change_password.html.twig');
UI::twigOutputBuffer();
}
} elseif ($page == 'change_language') {
@@ -277,11 +277,11 @@ if ($page == 'overview') {
$default_lang = $userinfo['def_language'];
}
UI::TwigBuffer('user/change_language.html.twig', [
UI::twigBuffer('user/change_language.html.twig', [
'languages' => $languages,
'default_lang' => $default_lang
]);
UI::TwigOutputBuffer();
UI::twigOutputBuffer();
}
} elseif ($page == 'change_theme') {
@@ -321,11 +321,11 @@ if ($page == 'overview') {
$themes_avail = \Froxlor\UI\Template::getThemes();
UI::TwigBuffer('user/change_theme.html.twig', [
UI::twigBuffer('user/change_theme.html.twig', [
'themes' => $themes_avail,
'default_theme' => $default_theme
]);
UI::TwigOutputBuffer();
UI::twigOutputBuffer();
}
} elseif ($page == 'send_error_report' && Settings::Get('system.allow_error_report_admin') == '1') {

View File

@@ -120,10 +120,10 @@ if ($page == 'ipsandports' || $page == 'overview') {
$ipsandports_add_data = include_once dirname(__FILE__) . '/lib/formfields/admin/ipsandports/formfield.ipsandports_add.php';
UI::TwigBuffer('user/form.html.twig', [
UI::twigBuffer('user/form.html.twig', [
'formdata' => $ipsandports_add_data['ipsandports_add']
]);
UI::TwigOutputBuffer();
UI::twigOutputBuffer();
}
} elseif ($action == 'edit' && $id != 0) {
try {
@@ -153,10 +153,10 @@ if ($page == 'ipsandports' || $page == 'overview') {
$ipsandports_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/ipsandports/formfield.ipsandports_edit.php';
UI::TwigBuffer('user/form.html.twig', [
UI::twigBuffer('user/form.html.twig', [
'formdata' => $ipsandports_edit_data['ipsandports_edit']
]);
UI::TwigOutputBuffer();
UI::twigOutputBuffer();
}
}
} elseif ($action == 'jqCheckIP') {

96
api.php
View File

@@ -1,88 +1,30 @@
<?php
use Froxlor\Api\Api;
use voku\helper\AntiXSS;
require __DIR__ . '/vendor/autoload.php';
require \Froxlor\Froxlor::getInstallDir() . '/lib/tables.inc.php';
// check whether API interface is enabled after all
if (\Froxlor\Settings::Get('api.enabled') != 1) {
// not enabled
header("Status: 404 Not found", 404);
header($_SERVER["SERVER_PROTOCOL"] . " 404 Not found", 404);
exit();
}
// we're talking json here
header("Content-Type:application/json");
// get our request
$request = @file_get_contents('php://input');
// check if present
if (empty($request)) {
json_response(400, "Invalid request");
}
// decode json request
$decoded_request = json_decode($request, true);
// is it valid?
if (is_null($decoded_request)) {
json_response(400, "Invalid JSON");
}
require __DIR__ . '/lib/tables.inc.php';
/**
* check for xss attempts and clean request
* This file is part of the Froxlor project.
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Froxlor team <team@froxlor.org> (2010-)
* @author Maurice Preuß <hello@envoyr.com>
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package API
*
*/
$antiXss = new AntiXSS();
$request = $antiXss->xss_clean($request);
// validate content
// Return response
try {
$decoded_request = stripcslashes_deep($decoded_request);
$request = \Froxlor\Api\FroxlorRPC::validateRequest($decoded_request);
// now actually do it
$cls = "\\Froxlor\\Api\\Commands\\" . $request['command']['class'];
$method = $request['command']['method'];
$apiObj = new $cls($decoded_request['header'], $request['params']);
// call the method with the params if any
echo $apiObj->$method();
echo (new Api)->handle(@file_get_contents('php://input'));
} catch (Exception $e) {
json_response($e->getCode(), $e->getMessage());
}
exit();
/**
* output json result
*
* @param int $status
* @param string $status_message
* @param mixed $data
*
* @return void
*/
function json_response($status, $status_message = '', $data = null)
{
if (isset($_SERVER["SERVER_PROTOCOL"]) && ! empty($_SERVER["SERVER_PROTOCOL"])) {
$resheader = $_SERVER["SERVER_PROTOCOL"] . " " . $status;
if (! empty($status_message)) {
$resheader .= ' ' . str_replace("\n", " ", $status_message);
}
header($resheader);
}
$response = array();
$response['status'] = $status;
$response['status_message'] = $status_message;
$response['data'] = $data;
$json_response = json_encode($response, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
echo $json_response;
exit();
}
function stripcslashes_deep($value)
{
return is_array($value) ? array_map('stripcslashes_deep', $value) : stripcslashes($value);
echo \Froxlor\Api\Response::jsonErrorResponse($e->getMessage(), $e->getCode());
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

1893
css/jquery-ui.min.css vendored

File diff suppressed because it is too large Load Diff

View File

@@ -103,12 +103,12 @@ if ($page == 'overview') {
$userinfo['total_bytes_used'] = 0;
}
UI::Twig()->addGlobal('userinfo', $userinfo);
UI::TwigBuffer('user/index.html.twig', [
UI::twig()->addGlobal('userinfo', $userinfo);
UI::twigBuffer('user/index.html.twig', [
'domains' => $domainArray,
'stdsubdomain' => $stdsubdomain
]);
UI::TwigOutputBuffer();
UI::twigOutputBuffer();
} elseif ($page == 'change_password') {

View File

@@ -17,197 +17,43 @@
*/
class FroxlorAPI
{
private string $url;
private string $key;
private string $secret;
private ?array $lastError = null;
private ?string $lastStatusCode = null;
/**
* URL to api.php of your froxlor installation
*
* @var string
*/
private $host = "";
/**
* your api-key
*
* @var string
*/
private $api_key = "";
/**
* your api-secret
*
* @var string
*/
private $api_secret = "";
/**
* last cURL error message
*
* @var string
*/
private $last_error = "";
/**
* last response header received
*
* @var array
*/
private $last_header = array();
/**
* last response data received
*
* @var array
*/
private $last_body = array();
/**
* create FroxlorAPI object
*
* @param string $host
* URL to api.php of your froxlor installation
* @param string $api_key
* your api-key
* @param string $api_secret
* your api-secret
*
* @return FroxlorAPI
*/
public function __construct(string $host, string $api_key, string $api_secret)
public function __construct($url, $key, $secret)
{
$this->host = $host;
$this->api_key = $api_key;
$this->api_secret = $api_secret;
$this->url = $url;
$this->key = $key;
$this->secret = $secret;
}
/**
* send request to froxlor api
*
* @param string $command
* @param array $params
*
* @return FroxlorAPI
*/
public function request(string $command, array $params = array()): FroxlorAPI
public function request($command, array $data = [])
{
// build request array
$request = [
'header' => [
'apikey' => $this->api_key,
'secret' => $this->api_secret
],
'body' => [
'command' => $command
]
$payload = [
'command' => $command,
'params' => $data
];
// add parameter to request-body if any
if (! empty($params)) {
$request['body']['params'] = $params;
}
// reset last data
$this->last_header = array();
$this->last_body = array();
// send actual request
$response = $this->requestCurl(json_encode($request));
// decode response
$resp = json_decode($response[1], true);
// set body to data-part of response
$this->last_body = $resp['data'];
// set header of response
$this->last_header = [
'status' => $resp['status'],
'status_message' => $resp['status_message']
];
// check for error in api response
if (isset($this->last_header['status']) && $this->last_header['status'] >= 400) {
// set last-error message
$this->last_error .= "[" . $this->last_header['status'] . "] " . $this->last_header['status_message'];
}
return $this;
}
/**
* returns last response header
*
* @return array status|status_message
*/
public function getLastHeader(): array
{
return $this->last_header;
}
/**
* returns last response data
*
* @return array
*/
public function getLastResponse(): array
{
if (!empty($this->getLastError())) {
// nothing is returned when the last call
// was not successful
return [];
}
return $this->last_body;
}
/**
* return last known error message
*
* @return string
*/
public function getLastError(): string
{
return $this->last_error;
}
/**
* send cURL request to api
*
* @param string $data
* json array
*
* @return array header|body
*/
private function requestCurl(string $data): array
{
// reset last error message
$this->last_error = "";
$ch = curl_init($this->host);
$ch = curl_init($this->url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERPWD, $this->key . ":" . $this->secret);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-type: application/json'
));
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_HEADER, 1);
$verbose = fopen('php://temp', 'w+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
if (! $data = curl_exec($ch)) {
$this->last_error = 'Curl execution error: ' . curl_error($ch) . "\n";
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
$this->last_error .= "Verbose information: " . htmlspecialchars($verboseLog) . "\n";
$this->lastStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
return json_decode($result ?? curl_error($ch), true);
}
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($data, 0, $header_size);
$body = substr($data, $header_size);
curl_close($ch);
return array(
$header,
$body
);
public function getLastStatusCode(): ?string
{
return $this->lastStatusCode;
}
}

View File

@@ -4,7 +4,7 @@
require __DIR__ . '/FroxlorAPI.php';
// create object of FroxlorAPI with URL, apikey and apisecret
$fapi = new FroxlorAPI('https://froxlor.your-host.tld/api.php', 'your-api-key', 'your-api-secret');
$fapi = new FroxlorAPI('http://127.0.0.1/api.php', 'your-api-key', 'your-api-secret');
// customer data
$data = [
@@ -16,19 +16,17 @@ $data = [
'new_customer_password' => 's0mEcRypt1cpassword' . uniqid()
];
// send request
$fapi->request('Customers.add', $data);
$response = $fapi->request('Customers.add', $data);
// check for error
if (! empty($fapi->getLastError())) {
echo "Error: " . $fapi->getLastError();
if ($fapi->getLastStatusCode() != 200) {
echo "HTTP-STATUS: " . $fapi->getLastStatusCode() . PHP_EOL;
echo "Description: " . $response['message'] . PHP_EOL;
exit();
}
// get response of request
$request = $fapi->getLastResponse();
// view response data
var_dump($request);
var_dump($response);
/*
array(60) {

View File

@@ -4,19 +4,17 @@
require __DIR__ . '/FroxlorAPI.php';
// create object of FroxlorAPI with URL, apikey and apisecret
$fapi = new FroxlorAPI('https://froxlor.your-host.tld/api.php', 'your-api-key', 'your-api-secret');
$fapi = new FroxlorAPI('http://localhost/api.php', 'your-api-key', 'your-api-secret');
// send request
$fapi->request('Froxlor.listFunctions');
$response = $fapi->request('Froxlor.listFunctions');
// check for error
if (! empty($fapi->getLastError())) {
echo "Error: " . $fapi->getLastError();
if ($fapi->getLastStatusCode() != 200) {
echo "HTTP-STATUS: " . $fapi->getLastStatusCode() . PHP_EOL;
echo "Description: " . $response['message'] . PHP_EOL;
exit();
}
// get response of request
$request = $fapi->getLastResponse();
// view response data
var_dump($request);
var_dump($response);

View File

@@ -385,7 +385,7 @@ if ($action == '2fa_entercode') {
$lastqrystr = htmlspecialchars($_REQUEST['qrystr'], ENT_QUOTES);
}
UI::TwigBuffer('login/login.html.twig', [
UI::twigBuffer('login/login.html.twig', [
'pagetitle' => 'Login',
'languages' => $languages,
'lastscript' => $lastscript,
@@ -394,7 +394,7 @@ if ($action == '2fa_entercode') {
'message' => $message,
'successmsg' => $successmessage
]);
UI::TwigOutputBuffer();
UI::twigOutputBuffer();
}
}
@@ -585,12 +585,12 @@ if ($action == 'forgotpwd') {
}
}
UI::TwigBuffer('login/fpwd.html.twig', [
UI::twigBuffer('login/fpwd.html.twig', [
'pagetitle' => $lng['login']['presend'],
'action' => $action,
'message' => $message,
]);
UI::TwigOutputBuffer();
UI::twigOutputBuffer();
}
if ($action == 'resetpwd') {

View File

@@ -53,10 +53,10 @@ require __DIR__ . '/lib/class.FroxlorInstall.php';
use Froxlor\UI\Panel\UI;
UI::initTwig(true);
UI::Twig()->addGlobal('install_mode', '1');
UI::Twig()->addGlobal('basehref', '../');
UI::twig()->addGlobal('install_mode', '1');
UI::twig()->addGlobal('basehref', '../');
$frxinstall = new FroxlorInstall();
$frxinstall->run();
UI::TwigOutputBuffer();
UI::twigOutputBuffer();

View File

@@ -133,7 +133,7 @@ class FroxlorInstall
$pagecontent = $result['pagecontent'];
$pagenavigation = $result['pagenavigation'];
UI::TwigBuffer('/install/index.html.twig', [
UI::twigBuffer('/install/index.html.twig', [
'pagetitle' => $pagetitle,
'pagecontent' => $pagecontent,
'pagenavigation' => $pagenavigation

176
lib/Froxlor/Ajax/Ajax.php Normal file
View File

@@ -0,0 +1,176 @@
<?php
namespace Froxlor\Ajax;
use Exception;
use Froxlor\Http\HttpClient;
use Froxlor\Settings;
use Froxlor\UI\Panel\UI;
/**
* This file is part of the Froxlor project.
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Froxlor team <team@froxlor.org> (2010-)
* @author Maurice Preuß <hello@envoyr.com>
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package AJAX
*
*/
class Ajax
{
protected string $session;
protected string $action;
protected string $theme;
/**
* @throws Exception
*/
public function __construct()
{
$this->session = $_GET['s'] ?? $_POST['s'] ?? null;
$this->action = $_GET['action'] ?? $_POST['action'] ?? null;
$this->theme = $_GET['theme'] ?? 'Froxlor';
}
/**
* @throws Exception
*/
public function handle()
{
$session = $this->getValidatedSession();
switch ($this->action) {
case 'newsfeed':
return $this->getNewsfeed();
case 'updatecheck':
return $this->getUpdateCheck($session);
default:
return $this->errorResponse('Action not found!');
}
}
public function errorResponse($message, int $response_code = 500)
{
return \Froxlor\Api\Response::jsonErrorResponse($message, $response_code);
}
public function jsonResponse($value, int $response_code = 200)
{
return \Froxlor\Api\Response::jsonResponse($value, $response_code);
}
/**
* @throws Exception
*/
private function getValidatedSession(): array
{
$remote_addr = $_SERVER['REMOTE_ADDR'];
if (empty($_SERVER['HTTP_USER_AGENT'])) {
$http_user_agent = 'unknown';
} else {
$http_user_agent = $_SERVER['HTTP_USER_AGENT'];
}
$timediff = time() - \Froxlor\Settings::Get('session.sessiontimeout');
$sel_stmt = \Froxlor\Database\Database::prepare("
SELECT * FROM `" . TABLE_PANEL_SESSIONS . "`
WHERE `hash` = :hash AND `ipaddress` = :ipaddr AND `useragent` = :ua AND `lastactivity` > :timediff
");
$session = \Froxlor\Database\Database::pexecute_first($sel_stmt, [
'hash' => $this->session,
'ipaddr' => $remote_addr,
'ua' => $http_user_agent,
'timediff' => $timediff
]);
if (!$session) {
throw new Exception('Session is not defined!');
}
return $session;
}
/**
* @throws Exception
*/
private function getNewsfeed()
{
UI::initTwig();
$feed = "https://inside.froxlor.org/news/";
// Set custom feed if provided
if (isset($_GET['role']) && $_GET['role'] == "customer") {
$custom_feed = Settings::Get("customer.news_feed_url");
if (!empty(trim($custom_feed))) {
$feed = $custom_feed;
}
}
// Check for simplexml_load_file
if (!function_exists("simplexml_load_file")) {
return $this->errorResponse(
"Newsfeed not available due to missing php-simplexml extension",
"Please install the php-simplexml extension in order to view our newsfeed."
);
}
// Check for curl_version
if (!function_exists('curl_version')) {
return $this->errorResponse(
"Newsfeed not available due to missing php-curl extension",
"Please install the php-curl extension in order to view our newsfeed."
);
}
$output = HttpClient::urlGet($feed);
$news = simplexml_load_string(trim($output));
// Handle items
if ($news) {
$items = null;
for ($i = 0; $i < 3; $i++) {
$item = $news->channel->item[$i];
$title = (string)$item->title;
$link = (string)$item->link;
$date = date("d.m.Y", strtotime($item->pubDate));
$content = preg_replace("/[\r\n]+/", " ", strip_tags($item->description));
$content = substr($content, 0, 150) . "...";
$items .= UI::twig()->render($this->theme . '/user/newsfeeditem.html.twig', [
'link' => $link,
'title' => $title,
'date' => $date,
'content' => $content
]);
}
return $items;
} else {
return $this->errorResponse('No Newsfeeds available at the moment.');
}
}
private function getUpdateCheck(array $session)
{
// TODO: set variables from current session
try {
return \Froxlor\Api\Commands\Froxlor::getLocal([
'adminid' => 1,
'adminsession' => 1,
'change_serversettings' => 1,
'loginname' => 'updatecheck'
])->checkUpdate();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
}
}

75
lib/Froxlor/Api/Api.php Normal file
View File

@@ -0,0 +1,75 @@
<?php
namespace Froxlor\Api;
use Exception;
use voku\helper\AntiXSS;
/**
* This file is part of the Froxlor project.
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Froxlor team <team@froxlor.org> (2010-)
* @author Maurice Preuß <hello@envoyr.com>
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package API
*
*/
class Api
{
protected array $headers;
/**
* Api constructor.
*
* @throws Exception
*/
public function __construct()
{
$this->headers = getallheaders();
// set header for the response
header("Accept: application/json");
header("Content-Type: application/json");
// check whether API interface is enabled after all
if (\Froxlor\Settings::Get('api.enabled') != 1) {
throw new Exception('API is not enabled. Please contact the administrator if you think this is wrong.', 400);
}
}
/**
* Handle incoming api request to our backend.
*
* @param mixed $request
* @throws Exception
*/
public function handle($request)
{
// validate content
$request = \Froxlor\Api\FroxlorRPC::validateRequest($request);
$request = (new AntiXSS())->xss_clean(
$this->stripcslashesDeep($request)
);
// now actually do it
$cls = "\\Froxlor\\Api\\Commands\\" . $request['command']['class'];
$method = $request['command']['method'];
$apiObj = new $cls([
'apikey' => $_SERVER['PHP_AUTH_USER'],
'secret' => $_SERVER['PHP_AUTH_PW']
], $request['params']);
// call the method with the params if any
return $apiObj->$method();
}
private function stripcslashesDeep($value)
{
return is_array($value) ? array_map([$this, 'stripcslashesDeep'], $value) : stripcslashes($value);
}
}

View File

@@ -243,7 +243,7 @@ abstract class ApiCommand extends ApiParameter
*/
protected function getUserDetail($detail = null)
{
return (isset($this->user_data[$detail]) ? $this->user_data[$detail] : null);
return ($this->user_data[$detail] ?? null);
}
/**
@@ -466,29 +466,13 @@ abstract class ApiCommand extends ApiParameter
/**
* return api-compatible response in JSON format and send corresponding http-header
*
* @param int $status
* @param string $status_message
* @param mixed $data
*
* @param int $response_code
* @return string json-encoded response message
*/
protected function response($status, $status_message, $data = null)
protected function response($data = null, int $response_code = 200)
{
if (isset($_SERVER["SERVER_PROTOCOL"]) && ! empty($_SERVER["SERVER_PROTOCOL"])) {
$resheader = $_SERVER["SERVER_PROTOCOL"] . " " . $status;
if (! empty($status_message)) {
$resheader .= ' ' . str_replace("\n", " ", $status_message);
}
header($resheader);
}
$response = array();
$response['status'] = $status;
$response['status_message'] = $status_message;
$response['data'] = $data;
$json_response = json_encode($response, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
return $json_response;
return \Froxlor\Api\Response::jsonDataResponse($data, $response_code);
}
/**

View File

@@ -51,7 +51,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -75,7 +75,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_admins']);
return $this->response($result['num_admins']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -109,7 +109,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get admin '" . $result['loginname'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
$key = ($id > 0 ? "id #" . $id : "loginname '" . $loginname . "'");
throw new \Exception("Admin with " . $key . " could not be found", 404);
@@ -364,7 +364,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Admins.get', array(
'id' => $adminid
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -677,7 +677,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Admins.get', array(
'id' => $result['adminid']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
}
}
@@ -775,7 +775,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted admin '" . $result['loginname'] . "'");
\Froxlor\User::updateCounters();
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -817,7 +817,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result['loginfail_count'] = 0;
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] unlocked admin '" . $result['loginname'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -23,8 +23,12 @@ class ApiKeys extends \Froxlor\Api\ApiCommand
{
public function listing()
{}
{
//
}
public function listingCount()
{}
{
//
}
}

View File

@@ -81,7 +81,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = $this->apiCall('Certificates.get', array(
'id' => $domain['id']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Domain '" . $domain['domain'] . "' already has a certificate. Did you mean to call update?", 406);
}
@@ -122,7 +122,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
if (! $result) {
throw new \Exception("Domain '" . $domain['domain'] . "' does not have a certificate.", 412);
}
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**
@@ -168,7 +168,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = $this->apiCall('Certificates.get', array(
'id' => $domain['id']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**
@@ -222,7 +222,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
}
$result[] = $cert;
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -258,7 +258,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$certs_stmt = Database::prepare($certs_stmt_query);
$result = Database::pexecute_first($certs_stmt, $qry_params, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_certs']);
return $this->response($result['num_certs']);
}
}
@@ -326,7 +326,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $chk['domain']);
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] removed ssl-certificate for '" . $chk['domain'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Unable to determine SSL certificate. Maybe no access?", 406);
}

View File

@@ -51,7 +51,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
'id' => $id
), true, true);
if ($result) {
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("cronjob with id #" . $id . " could not be found", 404);
}
@@ -119,7 +119,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
$result = $this->apiCall('Cronjobs.get', array(
'id' => $id
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -152,7 +152,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -175,7 +175,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_crons']);
return $this->response($result['num_crons']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);

View File

@@ -111,7 +111,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_CUSTOMER_BACKUP, $task_data);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] added customer-backup job for '" . $customer['loginname'] . "'. Target directory: " . $userpath);
return $this->response(200, "successful", $task_data);
return $this->response($task_data);
}
/**
@@ -170,7 +170,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
}
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list customer-backups");
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -204,7 +204,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$result_count ++;
}
}
return $this->response(200, "successful", $result_count);
return $this->response($result_count);
}
/**
@@ -239,7 +239,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
'tid' => $entry
), true, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] deleted planned customer-backup #" . $entry);
return $this->response(200, "successful", true);
return $this->response(true);
}
}
}

View File

@@ -103,7 +103,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
}
$result[] = $row;
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -133,7 +133,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
}
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_customers']);
return $this->response($result['num_customers']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -223,7 +223,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
}
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get customer '" . $result['loginname'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
$key = ($id > 0 ? "id #" . $id : "loginname '" . $loginname . "'");
throw new \Exception("Customer with " . $key . " could not be found", 404);
@@ -823,7 +823,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result = $this->apiCall('Customers.get', array(
'loginname' => $loginname
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("No more resources available", 406);
}
@@ -1420,7 +1420,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result = $this->apiCall('Customers.get', array(
'id' => $result['customerid']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**
@@ -1657,7 +1657,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted customer '" . $result['loginname'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -1699,7 +1699,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result['loginfail_count'] = 0;
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] unlocked customer '" . $result['loginname'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -1769,7 +1769,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result = $this->apiCall('Customers.get', array(
'id' => $c_result['customerid']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -128,7 +128,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('DirOptions.get', array(
'id' => $id
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**
@@ -186,7 +186,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get directory options for '" . $result['path'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
$key = "id #" . $id;
throw new \Exception("Directory option with " . $key . " could not be found", 404);
@@ -275,7 +275,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('DirOptions.get', array(
'id' => $id
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**
@@ -315,7 +315,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list directory-options");
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -347,7 +347,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_htaccess']);
return $this->response($result['num_htaccess']);
}
}
@@ -414,7 +414,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
), true, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted directory-option for '" . str_replace($customer_data['documentroot'], '/', $result['path']) . "'");
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**

View File

@@ -111,7 +111,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$result = $this->apiCall('DirProtections.get', array(
'id' => $id
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**
@@ -173,7 +173,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get directory protection for '" . $result['path'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
$key = ($id > 0 ? "id #" . $id : "username '" . $username . "'");
throw new \Exception("Directory protection with " . $key . " could not be found", 404);
@@ -258,7 +258,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$result = $this->apiCall('DirProtections.get', array(
'id' => $result['id']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**
@@ -298,7 +298,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list directory-protections");
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -330,7 +330,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_htpasswd']);
return $this->response($result['num_htpasswd']);
}
}
@@ -386,6 +386,6 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted htpasswd for '" . $result['username'] . " (" . $result['path'] . ")'");
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
return $this->response(200, "successful", $result);
return $this->response($result);
}
}

View File

@@ -341,7 +341,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$result = $this->apiCall('DomainZones.get', array(
'id' => $id
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
// return $errors
throw new \Exception(implode("\n", $errors), 406);
@@ -392,7 +392,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$zonefile = (string) $zone;
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get dns-zone for '" . $result['domain'] . "'");
return $this->response(200, "successful", explode("\n", $zonefile));
return $this->response(explode("\n", $zonefile));
}
/**
@@ -452,7 +452,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
while ($row = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -496,7 +496,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'did' => $id
), true, true);
if ($result) {
return $this->response(200, "successful", $result['num_dns']);
return $this->response($result['num_dns']);
}
}
@@ -543,8 +543,8 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
if ($del_stmt->rowCount() > 0) {
// re-generate bind configs
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
return $this->response(200, "successful", true);
return $this->response(true);
}
return $this->response(304, "successful", true);
return $this->response(null, 204);
}
}

View File

@@ -68,7 +68,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
}
$result[] = $row;
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -100,7 +100,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
}
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_domains']);
return $this->response($result['num_domains']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -156,7 +156,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$result['ipsandports'] = $this->getIpsForDomain($result['id']);
}
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get domain '" . $result['domain'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
$key = ($id > 0 ? "id #" . $id : "domainname '" . $domainname . "'");
throw new \Exception("Domain with " . $key . " could not be found", 404);
@@ -866,7 +866,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$result = $this->apiCall('Domains.get', array(
'domainname' => $domain
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
}
throw new \Exception("No more resources available", 406);
@@ -1833,7 +1833,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$result = $this->apiCall('Domains.get', array(
'domainname' => $result['domain']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -1994,7 +1994,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
// Using nameserver, insert a task which rebuilds the server config
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -273,7 +273,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("No more resources available", 406);
}
@@ -404,7 +404,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**
@@ -507,6 +507,6 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
Customers::decreaseUsage($customer['customerid'], 'email_quota_used', '', $quota);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted email account for '" . $result['email_full'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
}

View File

@@ -102,7 +102,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("No more resources available", 406);
}
@@ -168,7 +168,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
];
}
return $this->response(200, "successful", [
return $this->response([
'count' => count($destination),
'list' => $destination
]);
@@ -210,7 +210,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$result['destination'] = explode(' ', $result['destination']);
return $this->response(200, "successful", count($result['destination']));
return $this->response(count($result['destination']));
}
/**
@@ -280,7 +280,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Unknown forwarder id", 404);
}

View File

@@ -145,7 +145,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Emails.get', array(
'emailaddr' => $email_full
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("No more resources available", 406);
}
@@ -181,7 +181,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get email address '" . $result['email_full'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
$key = ($id > 0 ? "id #" . $id : "emailaddr '" . $emailaddr . "'");
throw new \Exception("Email address with " . $key . " could not be found", 404);
@@ -280,7 +280,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**
@@ -319,7 +319,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list email-addresses");
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -349,7 +349,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_emails']);
return $this->response($result['num_emails']);
}
}
@@ -423,6 +423,6 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
Customers::decreaseUsage($customer['customerid'], 'emails_used');
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted email address '" . $result['email_full'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
}

View File

@@ -70,7 +70,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$fpmdaemons[] = $row;
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($fpmdaemons),
'list' => $fpmdaemons
));
@@ -93,7 +93,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_fpms']);
return $this->response($result['num_fpms']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -121,7 +121,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
'id' => $id
), true, true);
if ($result) {
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("fpm-daemon with id #" . $id . " could not be found", 404);
}
@@ -234,7 +234,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('FpmDaemons.get', array(
'id' => $id
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -356,7 +356,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('FpmDaemons.get', array(
'id' => $id
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -402,7 +402,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] fpm-daemon setting '" . $result['description'] . "' has been deleted by '" . $this->getUserDetail('loginname') . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -74,7 +74,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
// zum update schritt #1 -> download
if ($isnewerversion == 1) {
$text = 'There is a newer version available: "' . $_version . '" (Your current version is: ' . $this->version . ')';
return $this->response(200, "successful", array(
return $this->response(array(
'isnewerversion' => $isnewerversion,
'version' => $_version,
'message' => $text,
@@ -83,7 +83,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
));
} elseif ($isnewerversion == 0) {
// all good
return $this->response(200, "successful", array(
return $this->response(array(
'isnewerversion' => $isnewerversion,
'version' => $version_label,
'message' => "",
@@ -95,13 +95,13 @@ class Froxlor extends \Froxlor\Api\ApiCommand
}
}
}
return $this->response(300, "successful", array(
return $this->response(array(
'isnewerversion' => 0,
'version' => $this->version . $this->branding,
'message' => 'Version-check not available due to missing php-curl extension',
'link' => UPDATE_URI . '/pretty',
'additional_info' => ""
));
), 502);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -129,7 +129,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
// cron.d file
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
return $this->response(200, "successful", true);
return $this->response(true);
} catch (\Exception $e) {
throw new \Exception($e->getMessage(), 406);
}
@@ -149,7 +149,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "User " . $this->getUserDetail('loginname') . " exported settings");
$json_export = \Froxlor\SImExporter::export();
return $this->response(200, "successful", $json_export);
return $this->response($json_export);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -175,7 +175,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
'value' => $row['value']
);
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -197,7 +197,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
{
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
$setting = $this->getParam('key');
return $this->response(200, "successful", Settings::Get($setting));
return $this->response(Settings::Get($setting));
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -227,7 +227,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
throw new \Exception("Setting '" . $setting . "' could not be found");
}
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] Changing setting '" . $setting . "' from '" . $oldvalue . "' to '" . $value . "'");
return $this->response(200, "successful", Settings::Set($setting, $value, true));
return $this->response(Settings::Set($setting, $value, true));
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -240,7 +240,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
*/
public function generatePassword()
{
return $this->response(200, "successful", \Froxlor\System\Crypt::generatePassword());
return $this->response(\Froxlor\System\Crypt::generatePassword());
}
/**
@@ -256,7 +256,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
$integrity = new \Froxlor\Database\IntegrityCheck();
$result = $integrity->checkAll();
if ($result) {
return $this->response(200, "successful", "OK");
return $this->response("OK");
}
throw new \Exception("Some checks failed.", 406);
}
@@ -333,7 +333,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
}
// return the list
return $this->response(200, "successful", $functions);
return $this->response($functions);
}
/**

View File

@@ -281,7 +281,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$result = $this->apiCall('Ftps.get', array(
'username' => $username
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
}
throw new \Exception("No more resources available", 406);
@@ -342,7 +342,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get ftp-user '" . $result['username'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
$key = ($id > 0 ? "id #" . $id : "username '" . $username . "'");
throw new \Exception("FTP user with " . $key . " could not be found", 404);
@@ -469,7 +469,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
'username' => $result['username']
));
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] updated ftp-user '" . $result['username'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**
@@ -505,7 +505,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list ftp-users");
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -533,7 +533,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_ftps']);
return $this->response($result['num_ftps']);
}
}
@@ -641,6 +641,6 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
Customers::decreaseUsage($customer_data['customerid'], 'ftps_used', $resetaccnumber);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] deleted ftp-user '" . $result['username'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
}

View File

@@ -57,7 +57,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -85,7 +85,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
}
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_plans']);
return $this->response($result['num_plans']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -120,7 +120,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get hosting-plan '" . $result['name'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
$key = ($id > 0 ? "id #" . $id : "planname '" . $planname . "'");
throw new \Exception("Hosting-plan with " . $key . " could not be found", 404);
@@ -246,7 +246,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = $this->apiCall('HostingPlans.get', array(
'planname' => $name
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -393,7 +393,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
);
Database::pexecute($upd_stmt, $update_data, true, true);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] updated hosting-plan '" . $result['name'] . "'");
return $this->response(200, "successful", $update_data);
return $this->response($update_data);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -431,7 +431,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
'id' => $id
), true, true);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted hosting-plan '" . $result['name'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -56,7 +56,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -82,7 +82,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
SELECT COUNT(*) as num_ips FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $ip_where);
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_ips']);
return $this->response($result['num_ips']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -116,7 +116,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
), true, true);
if ($result) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get ip " . $result['ip'] . " " . $result['port']);
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("IP/port with id #" . $id . " could not be found", 404);
}
@@ -310,7 +310,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$result = $this->apiCall('IpsAndPorts.get', array(
'id' => $ins_data['id']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -520,7 +520,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$result = $this->apiCall('IpsAndPorts.get', array(
'id' => $result['id']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -589,7 +589,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted IP/port '" . $result['ip'] . ":" . $result['port'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
} else {
\Froxlor\UI\Response::standard_error('cantdeletesystemip', '', true);
}

View File

@@ -182,7 +182,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Mysqls.get', array(
'dbname' => $username
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("No more resources available", 406);
}
@@ -273,7 +273,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
Database::needRoot(false);
$result['size'] = $mbdata['MB'] ?? 0;
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get database '" . $result['databasename'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
$key = ($id > 0 ? "id #" . $id : "dbname '" . $dbname . "'");
throw new \Exception("MySQL database with " . $key . " could not be found", 404);
@@ -365,7 +365,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Mysqls.get', array(
'dbname' => $result['databasename']
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**
@@ -436,7 +436,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
Database::needRoot(false);
}
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -463,7 +463,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_dbs']);
return $this->response($result['num_dbs']);
}
}
@@ -525,6 +525,6 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
Customers::decreaseUsage($customer['customerid'], 'mysqls_used', $resetaccnumber);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] deleted database '" . $result['databasename'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
}

View File

@@ -113,7 +113,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$phpconfigs[] = $row;
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($phpconfigs),
'list' => $phpconfigs
));
@@ -137,7 +137,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
");
$result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_phps']);
return $this->response($result['num_phps']);
}
}
throw new \Exception("Not allowed to execute given command.", 403);
@@ -165,7 +165,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'id' => $id
), true, true);
if ($result) {
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("php-config with id #" . $id . " could not be found", 404);
}
@@ -372,7 +372,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
));
$this->addForAllCustomers($allow_all_customers, $ins_data['id']);
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -573,7 +573,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
));
$this->addForAllCustomers($allow_all_customers, $id);
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}
@@ -624,7 +624,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] php setting '" . $result['description'] . "' has been deleted by '" . $this->getUserDetail('loginname') . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -370,7 +370,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('SubDomains.get', array(
'id' => $subdomain_id
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
throw new \Exception("No more resources available", 406);
}
@@ -451,7 +451,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get subdomain '" . $result['domain'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
$key = ($id > 0 ? "id #" . $id : "domainname '" . $domainname . "'");
throw new \Exception("Subdomain with " . $key . " could not be found", 404);
@@ -744,7 +744,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('SubDomains.get', array(
'id' => $id
));
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**
@@ -848,7 +848,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
while ($row = $domains_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
}
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -913,7 +913,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
");
$result = Database::pexecute_first($domains_stmt, null, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_subdom']);
return $this->response($result['num_subdom']);
}
}
@@ -1031,7 +1031,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
Customers::decreaseUsage($customer['customerid'], 'subdomains_used');
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] deleted subdomain '" . $result['domain'] . "'");
return $this->response(200, "successful", $result);
return $this->response($result);
}
/**

View File

@@ -74,7 +74,7 @@ class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list log-entries");
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));
@@ -129,7 +129,7 @@ class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
return $this->response(200, "successful", $result['num_logs']);
return $this->response($result['num_logs']);
}
}
@@ -204,7 +204,7 @@ class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$params['trunc'] = $truncatedate;
Database::pexecute($result_stmt, $params, true, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] truncated the froxlor syslog");
return $this->response(200, "successful", true);
return $this->response(true);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -144,7 +144,7 @@ class Traffic extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list traffic");
return $this->response(200, "successful", array(
return $this->response(array(
'count' => count($result),
'list' => $result
));

View File

@@ -1,6 +1,10 @@
<?php
namespace Froxlor\Api;
use Exception;
use voku\helper\AntiXSS;
/**
* This file is part of the Froxlor project.
* Copyright (c) 2010 the Froxlor Team (see authors).
@@ -11,6 +15,7 @@ namespace Froxlor\Api;
*
* @copyright (c) the authors
* @author Froxlor team <team@froxlor.org> (2010-)
* @author Maurice Preuß <hello@envoyr.com>
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package API
* @since 0.10.0
@@ -18,30 +23,35 @@ namespace Froxlor\Api;
*/
class FroxlorRPC
{
/**
* validate a given request
*
* @param array $request
*
* @throws \Exception
* @param $request
* @return array
* @throws Exception
*/
public static function validateRequest($request)
public static function validateRequest($request): array
{
// check header
if (! isset($request['header']) || empty($request['header'])) {
throw new \Exception("Invalid request header", 400);
// make basic authentication
if (!isset($_SERVER['PHP_AUTH_USER']) || !self::validateAuth($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) {
header('WWW-Authenticate: Basic realm="API"');
throw new Exception('Unauthenticated. Please provide api user credentials.', 401);
}
// check authorization
if (! isset($request['header']['apikey']) || empty($request['header']['apikey']) || ! isset($request['header']['secret']) || empty($request['header']['secret'])) {
throw new \Exception("No authorization credentials given", 400);
// check if present
if (empty($request)) {
throw new Exception('Empty request body.', 400);
}
self::validateAuth($request['header']['apikey'], $request['header']['secret']);
// check command
return self::validateBody($request);
// decode json request
$decoded_request = json_decode($request, true);
// is it valid?
if (is_null($decoded_request)) {
throw new Exception('Invalid JSON Format.', 400);
}
return self::validateBody($decoded_request);
}
/**
@@ -49,27 +59,28 @@ class FroxlorRPC
*
* @param string $key
* @param string $secret
*
* @throws \Exception
* @return boolean
*/
private static function validateAuth($key, $secret)
private static function validateAuth(string $key, string $secret): bool
{
$sel_stmt = \Froxlor\Database\Database::prepare("
$sel_stmt = \Froxlor\Database\Database::prepare(
"
SELECT ak.*, a.api_allowed as admin_api_allowed, c.api_allowed as cust_api_allowed, c.deactivated
FROM `api_keys` ak
LEFT JOIN `panel_admins` a ON a.adminid = ak.adminid
LEFT JOIN `panel_customers` c ON c.customerid = ak.customerid
WHERE `apikey` = :ak AND `secret` = :as
");
"
);
$result = \Froxlor\Database\Database::pexecute_first($sel_stmt, array(
'ak' => $key,
'as' => $secret
), true, true);
if ($result) {
if ($result['apikey'] == $key && $result['secret'] == $secret && ($result['valid_until'] == - 1 || $result['valid_until'] >= time()) && (($result['customerid'] == 0 && $result['admin_api_allowed'] == 1) || ($result['customerid'] > 0 && $result['cust_api_allowed'] == 1 && $result['deactivated'] == 0))) {
if ($result['apikey'] == $key && $result['secret'] == $secret && ($result['valid_until'] == -1 || $result['valid_until'] >= time(
)) && (($result['customerid'] == 0 && $result['admin_api_allowed'] == 1) || ($result['customerid'] > 0 && $result['cust_api_allowed'] == 1 && $result['deactivated'] == 0))) {
// get user to check whether api call is allowed
if (! empty($result['allowed_from'])) {
if (!empty($result['allowed_from'])) {
// @todo allow specification and validating of whole subnets later
$ip_list = explode(",", $result['allowed_from']);
$access_ip = inet_ntop(inet_pton($_SERVER['REMOTE_ADDR']));
@@ -81,7 +92,7 @@ class FroxlorRPC
}
}
}
throw new \Exception("Invalid authorization credentials", 403);
return false;
}
/**
@@ -90,37 +101,32 @@ class FroxlorRPC
* @param array $request
*
* @return array
* @throws \Exception
* @throws Exception
*/
private static function validateBody($request)
{
// check body
if (! isset($request['body']) || empty($request['body'])) {
throw new \Exception("Invalid request body", 400);
}
// check command exists
if (! isset($request['body']['command']) || empty($request['body']['command'])) {
throw new \Exception("No command given", 400);
if (empty($request['command'])) {
throw new Exception("Please provide a command.", 400);
}
$command = explode(".", $request['body']['command']);
$command = explode(".", $request['command']);
if (count($command) != 2) {
throw new \Exception("Invalid command", 400);
throw new Exception("The given command is invalid.", 400);
}
// simply check for file-existance, as we do not want to use our autoloader because this way
// it will recognize non-api classes+methods as valid commands
$apiclass = '\\Froxlor\\Api\\Commands\\' . $command[0];
if (! class_exists($apiclass) || ! @method_exists($apiclass, $command[1])) {
throw new \Exception("Unknown command", 400);
if (!class_exists($apiclass) || !@method_exists($apiclass, $command[1])) {
throw new Exception("Unknown command", 400);
}
return array(
'command' => array(
'class' => $command[0],
'method' => $command[1]
),
'params' => isset($request['body']['params']) ? $request['body']['params'] : null
'params' => $request['params'] ?? null
);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Froxlor\Api;
/**
* This file is part of the Froxlor project.
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Froxlor team <team@froxlor.org> (2010-)
* @author Maurice Preuß <hello@envoyr.com>
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package API
*
*/
class Response
{
public static function jsonResponse($data = null, int $response_code = 200)
{
http_response_code($response_code);
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
}
public static function jsonDataResponse($data = null, int $response_code = 200)
{
return self::jsonResponse(['data' => $data], $response_code);
}
public static function jsonErrorResponse($message = null, int $response_code = 200)
{
return self::jsonResponse(['message' => $message], $response_code);
}
}

View File

@@ -470,14 +470,14 @@ class Database
}
// show
\Froxlor\UI\Panel\UI::initTwig(true);
\Froxlor\UI\Panel\UI::Twig()->addGlobal('install_mode', '1');
\Froxlor\UI\Panel\UI::TwigBuffer('misc/dberrornice.html.twig', [
\Froxlor\UI\Panel\UI::twig()->addGlobal('install_mode', '1');
\Froxlor\UI\Panel\UI::twigBuffer('misc/dberrornice.html.twig', [
'page_title' => 'Database error',
'message' => $error_message,
'debug' => $error_trace,
'report' => $err_report_link
]);
echo \Froxlor\UI\Panel\UI::TwigOutputBuffer();
echo \Froxlor\UI\Panel\UI::twigOutputBuffer();
die();
}
die("We are sorry, but a MySQL - error occurred. The administrator may find more information in the syslog");

View File

@@ -1,17 +1,17 @@
<?php
namespace Froxlor\Http;
use Exception;
class HttpClient
{
/**
* Executes simple GET request
*
* @param string $url
*
* @return array
* @return bool|string
* @throws Exception
*/
public static function urlGet($url, $follow_location = true, $timeout = 10)
public static function urlGet(string $url, bool $follow_location = true, int $timeout = 10)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
@@ -25,7 +25,7 @@ class HttpClient
if ($output === false) {
$e = curl_error($ch);
curl_close($ch);
throw new \Exception("Curl error: " . $e);
throw new Exception("Curl error: " . $e);
}
curl_close($ch);
return $output;
@@ -34,12 +34,9 @@ class HttpClient
/**
* Downloads and stores a file from an url
*
* @param string $url
* @param string $target
*
* @return array
* @throws Exception
*/
public static function fileGet($url, $target)
public static function fileGet(string $url, string $target): array
{
$fh = fopen($target, 'w');
$ch = curl_init();
@@ -54,7 +51,7 @@ class HttpClient
if ($output === false) {
$e = curl_error($ch);
curl_close($ch);
throw new \Exception("Curl error: " . $e);
throw new Exception("Curl error: " . $e);
}
curl_close($ch);
return $output;

View File

@@ -142,8 +142,8 @@ class PhpHelper
// end later
$err_display .= '</div>';
// check for more existing errors
$errors = isset(\Froxlor\UI\Panel\UI::Twig()->getGlobals()['global_errors']) ? \Froxlor\UI\Panel\UI::Twig()->getGlobals()['global_errors'] : "";
\Froxlor\UI\Panel\UI::Twig()->addGlobal('global_errors', $errors . $err_display);
$errors = isset(\Froxlor\UI\Panel\UI::twig()->getGlobals()['global_errors']) ? \Froxlor\UI\Panel\UI::twig()->getGlobals()['global_errors'] : "";
\Froxlor\UI\Panel\UI::twig()->addGlobal('global_errors', $errors . $err_display);
// return true to ignore php standard error-handler
return true;
}
@@ -157,15 +157,15 @@ class PhpHelper
if (!isset($_SERVER['SHELL']) || (isset($_SERVER['SHELL']) && $_SERVER['SHELL'] == '')) {
// show
\Froxlor\UI\Panel\UI::initTwig(true);
\Froxlor\UI\Panel\UI::Twig()->addGlobal('install_mode', '1');
\Froxlor\UI\Panel\UI::TwigBuffer('misc/alert_nosession.html.twig', [
\Froxlor\UI\Panel\UI::twig()->addGlobal('install_mode', '1');
\Froxlor\UI\Panel\UI::twigBuffer('misc/alert_nosession.html.twig', [
'page_title' => 'Uncaught exception',
'heading' => 'Uncaught exception',
'type' => 'danger',
'alert_msg' => $exception->getCode() . ' ' . $exception->getMessage(),
'alert_info' => $exception->getTraceAsString()
]);
echo \Froxlor\UI\Panel\UI::TwigOutputBuffer();
echo \Froxlor\UI\Panel\UI::twigOutputBuffer();
die();
}
}

View File

@@ -128,7 +128,7 @@ class UI
*
* @return \Twig\Environment
*/
public static function Twig()
public static function twig(): ?\Twig\Environment
{
return self::$twig;
}
@@ -138,7 +138,7 @@ class UI
*
* @see \Twig\Environment::render()
*/
public static function TwigBuffer($name, array $context = [])
public static function twigBuffer($name, array $context = [])
{
self::$twigbuf[] = [
self::getTheme() . '/' . $name => $context
@@ -172,7 +172,7 @@ class UI
/**
* echo output buffer and empty buffer-content
*/
public static function TwigOutputBuffer()
public static function twigOutputBuffer()
{
$output = "";
foreach (self::$twigbuf as $buf) {
@@ -254,8 +254,9 @@ class UI
* returns an array of available themes
*
* @return array
* @throws \Exception
*/
public static function getThemes()
public static function getThemes(): array
{
$themespath = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/templates/');
$themes_available = array();

View File

@@ -119,14 +119,14 @@ class Response
if ($throw_exception) {
throw new \Exception(strip_tags($error), 400);
}
\Froxlor\UI\Panel\UI::TwigBuffer('misc/alert.html.twig', [
\Froxlor\UI\Panel\UI::twigBuffer('misc/alert.html.twig', [
'type' => 'danger',
'btntype' => 'light',
'heading' => $lng['error']['error'],
'alert_msg' => $error,
'redirect_link' => $link_ref
]);
\Froxlor\UI\Panel\UI::TwigOutputBuffer();
\Froxlor\UI\Panel\UI::twigOutputBuffer();
exit;
}

View File

@@ -1,20 +1,28 @@
<?php
namespace Froxlor;
use Exception;
use Froxlor\Ajax\Ajax;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
/**
* This file is part of the Froxlor project.
* Copyright (c) 2013 the Froxlor Team (see authors).
* Copyright (c) 2010 the Froxlor Team (see authors).
*
* For the full copyright and license information, please view the COPYING
* file that was distributed with this source code. You can also view the
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
*
* @copyright (c) the authors
* @author Roman Schmerold <bnoize@froxlor.org>
* @author Froxlor team <team@froxlor.org> (2010-)
* @author Maurice Preuß <hello@envoyr.com>
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package AJAX
*
*/
require_once dirname(__DIR__) . '/vendor/autoload.php';
// Load the user settings
@@ -24,120 +32,9 @@ if (!file_exists('./userdata.inc.php')) {
require './userdata.inc.php';
require './tables.inc.php';
use Froxlor\UI\Panel\UI;
if (isset($_POST['s'])) {
$s = $_POST['s'];
} elseif (isset($_GET['s'])) {
$s = $_GET['s'];
} else {
$s = '';
}
if (isset($_POST['action'])) {
$action = $_POST['action'];
} elseif (isset($_GET['action'])) {
$action = $_GET['action'];
} else {
$action = "";
}
$theme = $_GET['theme'] ?? 'Froxlor';
UI::sendHeaders();
UI::initTwig();
UI::sendSslHeaders();
ini_set("session.name", "s");
ini_set("url_rewriter.tags", "");
ini_set("session.use_cookies", false);
ini_set("session.cookie_httponly", true);
ini_set("session.cookie_secure", UI::$SSL_REQ);
session_id($s);
session_start();
if (empty($s)) {
die();
}
$remote_addr = $_SERVER['REMOTE_ADDR'];
if (empty($_SERVER['HTTP_USER_AGENT'])) {
$http_user_agent = 'unknown';
} else {
$http_user_agent = $_SERVER['HTTP_USER_AGENT'];
}
$timediff = time() - \Froxlor\Settings::Get('session.sessiontimeout');
$sel_stmt = \Froxlor\Database\Database::prepare("
SELECT * FROM `" . TABLE_PANEL_SESSIONS . "`
WHERE `hash` = :hash AND `ipaddress` = :ipaddr AND `useragent` = :ua AND `lastactivity` > :timediff
");
$sinfo = \Froxlor\Database\Database::pexecute_first($sel_stmt, [
'hash' => $s,
'ipaddr' => $remote_addr,
'ua' => $http_user_agent,
'timediff' => $timediff
]);
if ($sinfo == false) {
die();
}
if ($action == "newsfeed") {
if (isset($_GET['role']) && $_GET['role'] == "customer") {
$feed = \Froxlor\Settings::Get("customer.news_feed_url");
if (empty(trim($feed))) {
$feed = "https://inside.froxlor.org/news/";
}
} else {
$feed = "https://inside.froxlor.org/news/";
}
if (function_exists("simplexml_load_file") == false) {
outputItem("Newsfeed not available due to missing php-simplexml extension", "Please install the php-simplexml extension in order to view our newsfeed.");
exit();
}
if (function_exists('curl_version')) {
$output = \Froxlor\Http\HttpClient::urlGet($feed);
$news = simplexml_load_string(trim($output));
} else {
outputItem("Newsfeed not available due to missing php-curl extension", "Please install the php-curl extension in order to view our newsfeed.");
exit();
}
if ($news !== false) {
for ($i = 0; $i < 3; $i++) {
$item = $news->channel->item[$i];
$title = (string) $item->title;
$link = (string) $item->link;
$date = date("d.m.Y", strtotime($item->pubDate));
$content = preg_replace("/[\r\n]+/", " ", strip_tags($item->description));
$content = substr($content, 0, 150) . "...";
echo UI::Twig()->render($theme . '/user/newsfeeditem.html.twig', [
'link' => $link,
'title' => $title,
'date' => $date,
'content' => $content
]);
}
} else {
echo "";
}
} elseif ($action == "updatecheck") {
try {
$json_result = \Froxlor\Api\Commands\Froxlor::getLocal([
'adminid' => 1,
'adminsession' => 1,
'change_serversettings' => 1,
'loginname' => 'updatecheck'
])->checkUpdate();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
echo $result;
} else {
echo "No action set.";
// Return response
try {
echo (new Ajax)->handle();
} catch (Exception $e) {
echo \Froxlor\Api\Response::jsonErrorResponse($e->getMessage(), 500);
}

View File

@@ -93,8 +93,8 @@ $filename = htmlentities(basename($_SERVER['SCRIPT_NAME']));
// check whether the userdata file exists
if (!file_exists(\Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php')) {
UI::Twig()->addGlobal('install_mode', '1');
echo UI::Twig()->render($_deftheme . '/misc/configurehint.html.twig');
UI::twig()->addGlobal('install_mode', '1');
echo UI::twig()->render($_deftheme . '/misc/configurehint.html.twig');
die();
}
@@ -103,8 +103,8 @@ if (!is_readable(\Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php')) {
// get possible owner
$posixusername = posix_getpwuid(posix_getuid());
$posixgroup = posix_getgrgid(posix_getgid());
UI::Twig()->addGlobal('install_mode', '1');
echo UI::Twig()->render($_deftheme . '/misc/ownershiphint.html.twig', [
UI::twig()->addGlobal('install_mode', '1');
echo UI::twig()->render($_deftheme . '/misc/ownershiphint.html.twig', [
'user' => $posixusername['name'],
'group' => $posixgroup['name'],
'installdir' => \Froxlor\Froxlor::getInstallDir()
@@ -115,8 +115,8 @@ if (!is_readable(\Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php')) {
// include MySQL-Username/Passwort etc.
require \Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php';
if (!isset($sql) || !is_array($sql)) {
UI::Twig()->addGlobal('install_mode', '1');
echo UI::Twig()->render($_deftheme . '/misc/configurehint.html.twig');
UI::twig()->addGlobal('install_mode', '1');
echo UI::twig()->render($_deftheme . '/misc/configurehint.html.twig');
die();
}
@@ -361,8 +361,8 @@ if (Settings::Get('panel.logo_overridecustom') == 0 && file_exists($hl_path . '/
}
}
UI::Twig()->addGlobal('header_logo_login', $header_logo_login);
UI::Twig()->addGlobal('header_logo', $header_logo);
UI::twig()->addGlobal('header_logo_login', $header_logo_login);
UI::twig()->addGlobal('header_logo', $header_logo);
/**
* Redirects to index.php (login page) if no session exists
@@ -377,7 +377,7 @@ if ($nosession == 1 && AREA != 'login') {
exit();
}
UI::Twig()->addGlobal('userinfo', ($userinfo ?? []));
UI::twig()->addGlobal('userinfo', ($userinfo ?? []));
/**
* Logic moved out of lng-file
@@ -433,7 +433,7 @@ if (AREA == 'admin' || AREA == 'customer') {
$navigation = \Froxlor\UI\HTML::buildNavigation($navigation_data[AREA], $userinfo);
}
}
UI::Twig()->addGlobal('nav_entries', $navigation);
UI::twig()->addGlobal('nav_entries', $navigation);
$js = "";
$css = "";
@@ -454,8 +454,8 @@ if (is_array($_themeoptions) && array_key_exists('js', $_themeoptions['variants'
}
}
UI::Twig()->addGlobal('theme_js', $js);
UI::Twig()->addGlobal('theme_css', $css);
UI::twig()->addGlobal('theme_js', $js);
UI::twig()->addGlobal('theme_css', $css);
unset($js);
unset($css);
@@ -500,9 +500,9 @@ if ($page == '') {
$page = 'overview';
}
UI::Twig()->addGlobal('action', $action);
UI::Twig()->addGlobal('page', $page);
UI::Twig()->addGlobal('s', $s);
UI::twig()->addGlobal('action', $action);
UI::twig()->addGlobal('page', $page);
UI::twig()->addGlobal('s', $s);
/**
* Initialize the mailingsystem

View File

@@ -16,39 +16,40 @@
* @package System
*
*/
define('TABLE_FTP_GROUPS', 'ftp_groups');
define('TABLE_FTP_USERS', 'ftp_users');
define('TABLE_FTP_QUOTALIMITS', 'ftp_quotalimits');
define('TABLE_FTP_QUOTATALLIES', 'ftp_quotatallies');
define('TABLE_MAIL_AUTORESPONDER', 'mail_autoresponder');
define('TABLE_MAIL_USERS', 'mail_users');
define('TABLE_MAIL_VIRTUAL', 'mail_virtual');
define('TABLE_PANEL_ACTIVATION', 'panel_activation');
define('TABLE_PANEL_ADMINS', 'panel_admins');
define('TABLE_PANEL_CUSTOMERS', 'panel_customers');
define('TABLE_PANEL_DATABASES', 'panel_databases');
define('TABLE_PANEL_DOMAINS', 'panel_domains');
define('TABLE_PANEL_HTACCESS', 'panel_htaccess');
define('TABLE_PANEL_HTPASSWDS', 'panel_htpasswds');
define('TABLE_PANEL_SESSIONS', 'panel_sessions');
define('TABLE_PANEL_SETTINGS', 'panel_settings');
define('TABLE_PANEL_TASKS', 'panel_tasks');
define('TABLE_PANEL_TEMPLATES', 'panel_templates');
define('TABLE_PANEL_TRAFFIC', 'panel_traffic');
define('TABLE_PANEL_TRAFFIC_ADMINS', 'panel_traffic_admins');
define('TABLE_PANEL_DISKSPACE', 'panel_diskspace');
define('TABLE_PANEL_LANGUAGE', 'panel_languages');
define('TABLE_PANEL_IPSANDPORTS', 'panel_ipsandports');
define('TABLE_PANEL_LOG', 'panel_syslog');
define('TABLE_PANEL_PHPCONFIGS', 'panel_phpconfigs');
define('TABLE_PANEL_CRONRUNS', 'cronjobs_run');
define('TABLE_PANEL_REDIRECTCODES', 'redirect_codes');
define('TABLE_PANEL_DOMAINREDIRECTS', 'domain_redirect_codes');
define('TABLE_PANEL_DOMAIN_SSL_SETTINGS', 'domain_ssl_settings');
define('TABLE_DOMAINTOIP', 'panel_domaintoip');
define('TABLE_DOMAIN_DNS', 'domain_dns_entries');
define('TABLE_PANEL_FPMDAEMONS', 'panel_fpmdaemons');
define('TABLE_PANEL_PLANS', 'panel_plans');
define('TABLE_API_KEYS', 'api_keys');
const TABLE_FTP_GROUPS = 'ftp_groups';
const TABLE_FTP_USERS = 'ftp_users';
const TABLE_FTP_QUOTALIMITS = 'ftp_quotalimits';
const TABLE_FTP_QUOTATALLIES = 'ftp_quotatallies';
const TABLE_MAIL_AUTORESPONDER = 'mail_autoresponder';
const TABLE_MAIL_USERS = 'mail_users';
const TABLE_MAIL_VIRTUAL = 'mail_virtual';
const TABLE_PANEL_ACTIVATION = 'panel_activation';
const TABLE_PANEL_ADMINS = 'panel_admins';
const TABLE_PANEL_CUSTOMERS = 'panel_customers';
const TABLE_PANEL_DATABASES = 'panel_databases';
const TABLE_PANEL_DOMAINS = 'panel_domains';
const TABLE_PANEL_HTACCESS = 'panel_htaccess';
const TABLE_PANEL_HTPASSWDS = 'panel_htpasswds';
const TABLE_PANEL_SESSIONS = 'panel_sessions';
const TABLE_PANEL_SETTINGS = 'panel_settings';
const TABLE_PANEL_TASKS = 'panel_tasks';
const TABLE_PANEL_TEMPLATES = 'panel_templates';
const TABLE_PANEL_TRAFFIC = 'panel_traffic';
const TABLE_PANEL_TRAFFIC_ADMINS = 'panel_traffic_admins';
const TABLE_PANEL_DISKSPACE = 'panel_diskspace';
const TABLE_PANEL_LANGUAGE = 'panel_languages';
const TABLE_PANEL_IPSANDPORTS = 'panel_ipsandports';
const TABLE_PANEL_LOG = 'panel_syslog';
const TABLE_PANEL_PHPCONFIGS = 'panel_phpconfigs';
const TABLE_PANEL_CRONRUNS = 'cronjobs_run';
const TABLE_PANEL_REDIRECTCODES = 'redirect_codes';
const TABLE_PANEL_DOMAINREDIRECTS = 'domain_redirect_codes';
const TABLE_PANEL_DOMAIN_SSL_SETTINGS = 'domain_ssl_settings';
const TABLE_DOMAINTOIP = 'panel_domaintoip';
const TABLE_DOMAIN_DNS = 'domain_dns_entries';
const TABLE_PANEL_FPMDAEMONS = 'panel_fpmdaemons';
const TABLE_PANEL_PLANS = 'panel_plans';
const TABLE_API_KEYS = 'api_keys';
require dirname(__FILE__) . '/version.inc.php';

View File

@@ -3198,10 +3198,76 @@ function withinMaxClamp(min, value, max) {
/***/ }),
/***/ "./templates/Froxlor/src/main.js":
/*!***************************************!*\
!*** ./templates/Froxlor/src/main.js ***!
\***************************************/
/***/ "./templates/Froxlor/src/js/components/newsfeed.js":
/*!*********************************************************!*\
!*** ./templates/Froxlor/src/js/components/newsfeed.js ***!
\*********************************************************/
/***/ (() => {
$(document).ready(function () {
/*
* newsfeed
*/
if (document.getElementById('newsfeed')) {
var role = "";
if (typeof $("#newsfeed").data("role") !== "undefined") {
role = "&role=" + $("#newsfeed").data("role");
}
$.ajax({
url: "lib/ajax.php?action=newsfeed" + role + "&theme=" + window.$theme + "&s=" + window.$session,
type: "GET",
success: function success(data) {
$("#newsfeeditems").html(data);
},
error: function error(request, status, _error) {
console.log(request, status, _error);
$("#newsfeeditems").html('<div class="alert alert-warning" role="alert">Error loading newsfeed</div>');
}
});
}
});
/***/ }),
/***/ "./templates/Froxlor/src/js/components/updatecheck.js":
/*!************************************************************!*\
!*** ./templates/Froxlor/src/js/components/updatecheck.js ***!
\************************************************************/
/***/ (() => {
$(document).ready(function () {
/*
* updatecheck
*/
if (document.getElementById('updatecheck')) {
var role = "";
if (typeof $("#updatecheck").data("role") !== "undefined") {
role = "&role=" + $("#newsfeed").data("role");
}
$.ajax({
url: "lib/ajax.php?action=updatecheck" + role + "&theme=" + window.$theme + "&s=" + window.$session,
type: "GET",
success: function success(data) {
$("#newsfeeditems").html(data);
},
error: function error(request, status, _error) {
console.log(request, status, _error);
$("#newsfeeditems").html('<div class="alert alert-warning" role="alert">Error loading newsfeed</div>');
}
});
}
});
/***/ }),
/***/ "./templates/Froxlor/src/js/main.js":
/*!******************************************!*\
!*** ./templates/Froxlor/src/js/main.js ***!
\******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
@@ -3212,30 +3278,13 @@ __webpack_require__.r(__webpack_exports__);
window.$ = window.jQuery = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js");
$(document).ready(function () {
var mytheme = 'Froxlor';
/*
* newsfeed
*/
window.$theme = 'Froxlor';
window.$session = $('meta[name="froxlor-session"]').attr('content');
}); // Load components
if (document.getElementById('newsfeed')) {
var role = "";
__webpack_require__(/*! ./components/newsfeed */ "./templates/Froxlor/src/js/components/newsfeed.js");
if (typeof $("#newsfeed").data("role") !== "undefined") {
role = "&role=" + $("#newsfeed").data("role");
}
$.ajax({
url: "lib/ajax.php?action=newsfeed" + role + "&theme=" + mytheme,
type: "GET",
success: function success(data) {
$("#newsfeeditems").html(data);
},
error: function error(a, b) {
$("#newsfeeditems").html('<div class="alert alert-warning" role="alert">Error loading newsfeed</div>');
}
});
}
});
__webpack_require__(/*! ./components/updatecheck */ "./templates/Froxlor/src/js/components/updatecheck.js");
/***/ }),
@@ -19334,7 +19383,7 @@ __webpack_require__.r(__webpack_exports__);
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
/******/ __webpack_require__.O(undefined, ["templates/Froxlor/assets/css/dark","templates/Froxlor/assets/css/main"], () => (__webpack_require__("./templates/Froxlor/src/main.js")))
/******/ __webpack_require__.O(undefined, ["templates/Froxlor/assets/css/dark","templates/Froxlor/assets/css/main"], () => (__webpack_require__("./templates/Froxlor/src/js/main.js")))
/******/ __webpack_require__.O(undefined, ["templates/Froxlor/assets/css/dark","templates/Froxlor/assets/css/main"], () => (__webpack_require__("./templates/Froxlor/src/scss/main.scss")))
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["templates/Froxlor/assets/css/dark","templates/Froxlor/assets/css/main"], () => (__webpack_require__("./templates/Froxlor/src/scss/dark.scss")))
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);

View File

@@ -7,6 +7,9 @@
<meta name="robots" content="noindex, nofollow, noarchive"/>
<meta name="googlebot" content="nosnippet"/>
<!-- Session -->
<meta name="froxlor-session" content="{{ s }}">
<!-- CSS -->
{% if theme_css is empty %}
<link href="{{ basehref|default('') }}templates/Froxlor/assets/css/main.css" rel="stylesheet" type="text/css" />

View File

@@ -0,0 +1,24 @@
$(document).ready(function () {
/*
* newsfeed
*/
if (document.getElementById('newsfeed')) {
let role = "";
if (typeof $("#newsfeed").data("role") !== "undefined") {
role = "&role=" + $("#newsfeed").data("role");
}
$.ajax({
url: "lib/ajax.php?action=newsfeed" + role + "&theme=" + window.$theme + "&s=" + window.$session,
type: "GET",
success: function (data) {
$("#newsfeeditems").html(data);
},
error: function (request, status, error) {
console.log(request, status, error)
$("#newsfeeditems").html('<div class="alert alert-warning" role="alert">Error loading newsfeed</div>');
}
});
}
});

View File

@@ -0,0 +1,24 @@
$(document).ready(function () {
/*
* updatecheck
*/
if (document.getElementById('updatecheck')) {
let role = "";
if (typeof $("#updatecheck").data("role") !== "undefined") {
role = "&role=" + $("#newsfeed").data("role");
}
$.ajax({
url: "lib/ajax.php?action=updatecheck" + role + "&theme=" + window.$theme + "&s=" + window.$session,
type: "GET",
success: function (data) {
$("#newsfeeditems").html(data);
},
error: function (request, status, error) {
console.log(request, status, error)
$("#newsfeeditems").html('<div class="alert alert-warning" role="alert">Error loading newsfeed</div>');
}
});
}
});

View File

@@ -0,0 +1,14 @@
// load bootstrap
import 'bootstrap';
// load jquery
window.$ = window.jQuery = require('jquery');
$(document).ready(function () {
window.$theme = 'Froxlor';
window.$session = $('meta[name="froxlor-session"]').attr('content');
});
// Load components
require('./components/newsfeed')
require('./components/updatecheck')

View File

@@ -1,43 +0,0 @@
// load bootstrap
import 'bootstrap';
// load jquery
window.$ = window.jQuery = require('jquery');
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
$(document).ready(function () {
const mytheme = 'Froxlor';
/*
* newsfeed
*/
if (document.getElementById('newsfeed')) {
var role = "";
if (typeof $("#newsfeed").data("role") !== "undefined") {
role = "&role=" + $("#newsfeed").data("role");
}
var s = getUrlVars()["s"];
$.ajax({
url: "lib/ajax.php?action=newsfeed" + role + "&theme=" + mytheme + "&s=" + s,
type: "GET",
success: function (data) {
$("#newsfeeditems").html(data);
},
error: function (a, b) {
$("#newsfeeditems").html('<div class="alert alert-warning" role="alert">Error loading newsfeed</div>');
}
});
}
});

View File

@@ -32,6 +32,11 @@
</div>
<div class="collapse navbar-collapse justify-content-end px-3" id="navbar">
<ul class="navbar-nav align-items-center">
<li class="nav-item text-nowrap d-block">
<a class="btn btn-link" title="{{ lng('login.logout') }}" href="{{ linker({'section': 'index', 'action': 'logout'}) }}">
<i class="fas fa-power-off"></i>
</a>
</li>
<li class="nav-item text-nowrap d-block me-2">
<a class="btn btn-primary btn-sm d-block" href="{{ linker({'section': 'index'}) }}">
<i class="fa fa-dashboard"></i> {{ lng('panel.dashboard') }}

View File

@@ -3,6 +3,6 @@
let mix = require('laravel-mix');
mix
.js('templates/Froxlor/src/main.js', 'templates/Froxlor/assets/js')
.js('templates/Froxlor/src/js/main.js', 'templates/Froxlor/assets/js')
.sass('templates/Froxlor/src/scss/main.scss', 'templates/Froxlor/assets/css')
.sass('templates/Froxlor/src/scss/dark.scss', 'templates/Froxlor/assets/css');