diff --git a/.github/workflows/build-mysql.yml b/.github/workflows/build-mysql.yml
index aa774291dc..21927a0743 100644
--- a/.github/workflows/build-mysql.yml
+++ b/.github/workflows/build-mysql.yml
@@ -39,16 +39,7 @@ jobs:
- name: Wait for database
run: sleep 15
- - name: Setup database (8.0)
- if: matrix.mysql-version == '8.0'
- run: |
- mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'%' IDENTIFIED WITH mysql_native_password BY 'fr0xl0r.TravisCI';"
- mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'%';"
- php -r "echo include('install/froxlor.sql.php');" > /tmp/froxlor.sql
- mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < /tmp/froxlor.sql
-
- - name: Setup database (5.7)
- if: matrix.mysql-version == '5.7'
+ - name: Setup database
run: |
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'%' IDENTIFIED BY 'fr0xl0r.TravisCI';"
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'%';"
diff --git a/2fa.php b/2fa.php
index b90cc0d279..635acf313c 100644
--- a/2fa.php
+++ b/2fa.php
@@ -33,6 +33,7 @@
use Froxlor\FroxlorTwoFactorAuth;
use Froxlor\Settings;
use Froxlor\UI\Panel\UI;
+use Froxlor\UI\Request;
use Froxlor\UI\Response;
use Froxlor\PhpHelper;
use Froxlor\User;
@@ -63,7 +64,7 @@
]);
Response::standardSuccess('2fa.2fa_removed');
} elseif ($action == 'preadd') {
- $type = isset($_POST['type_2fa']) ? $_POST['type_2fa'] : '0';
+ $type = Request::post('type_2fa', '0');
$data = "";
if ($type > 0) {
@@ -107,9 +108,9 @@
Response::dynamicError('Select one of the possible values for 2FA');
}
} elseif ($action == 'add') {
- $type = isset($_POST['type_2fa']) ? $_POST['type_2fa'] : '0';
- $data = isset($_POST['data_2fa']) ? $_POST['data_2fa'] : '';
- $code = isset($_POST['codevalidation']) ? $_POST['codevalidation'] : '';
+ $type = Request::post('type_2fa', '0');
+ $data = Request::post('data_2fa', '');
+ $code = Request::post('codevalidation', '');
// validate
$result = $tfa->verifyCode($data, $code, 3);
diff --git a/actions/admin/settings/110.accounts.php b/actions/admin/settings/110.accounts.php
index cff3235665..07e4099a83 100644
--- a/actions/admin/settings/110.accounts.php
+++ b/actions/admin/settings/110.accounts.php
@@ -35,6 +35,7 @@
'varname' => 'sessiontimeout',
'type' => 'number',
'min' => 60,
+ 'max' => 31536000,
'default' => 600,
'save_method' => 'storeSettingField'
],
diff --git a/admin_admins.php b/admin_admins.php
index 98a522f2a1..2399f778d3 100644
--- a/admin_admins.php
+++ b/admin_admins.php
@@ -106,7 +106,7 @@
Response::standardError('youcantdeleteyourself');
}
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
Admins::getLocal($userinfo, [
'id' => $id
])->delete();
@@ -122,9 +122,9 @@
}
}
} elseif ($action == 'add') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- Admins::getLocal($userinfo, $_POST)->add();
+ Admins::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -159,9 +159,9 @@
$result = json_decode($json_result, true)['data'];
if ($result['loginname'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- Admins::getLocal($userinfo, $_POST)->update();
+ Admins::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
diff --git a/admin_apcuinfo.php b/admin_apcuinfo.php
index f4a7e3408c..f9d96cff92 100644
--- a/admin_apcuinfo.php
+++ b/admin_apcuinfo.php
@@ -33,6 +33,7 @@
use Froxlor\FroxlorLogger;
use Froxlor\UI\Panel\UI;
+use Froxlor\UI\Request;
use Froxlor\UI\Response;
use Froxlor\UI\HTML;
@@ -42,7 +43,7 @@
$horizontal_bar_size = 950; // 1280px window width
if ($action == 'delete' && function_exists('apcu_clear_cache') && $userinfo['change_serversettings'] == '1') {
- if ($_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
apcu_clear_cache();
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_INFO, "cleared APCu cache");
header('Location: ' . $linker->getLink([
diff --git a/admin_autoupdate.php b/admin_autoupdate.php
index dcaedae881..0c76152be5 100644
--- a/admin_autoupdate.php
+++ b/admin_autoupdate.php
@@ -32,6 +32,7 @@
use Froxlor\Install\AutoUpdate;
use Froxlor\Settings;
use Froxlor\UI\Panel\UI;
+use Froxlor\UI\Request;
use Froxlor\UI\Response;
if ($page != 'error') {
@@ -110,7 +111,7 @@
} // download the new archive
elseif ($page == 'getdownload') {
// retrieve the new version from the form
- $newversion = isset($_POST['newversion']) ? $_POST['newversion'] : null;
+ $newversion = Request::post('newversion');
$result = 6;
// valid?
@@ -130,8 +131,8 @@
]);
} // extract and install new version
elseif ($page == 'extract') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
- $toExtract = isset($_POST['archive']) ? $_POST['archive'] : null;
+ if (Request::post('send') == 'send') {
+ $toExtract = Request::post('archive');
$localArchive = FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/updates/' . $toExtract);
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "Extracting " . $localArchive . " to " . Froxlor::getInstallDir());
$result = AutoUpdate::extractZip($localArchive);
@@ -145,7 +146,7 @@
// redirect to update-page
Response::redirectTo('admin_updates.php');
} else {
- $toExtract = isset($_GET['archive']) ? $_GET['archive'] : null;
+ $toExtract = Request::get('archive');
$localArchive = FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/updates/' . $toExtract);
}
@@ -192,7 +193,7 @@
} // display error
elseif ($page == 'error') {
// retrieve error-number via url-parameter
- $errno = isset($_GET['errno']) ? (int)$_GET['errno'] : 0;
+ $errno = Request::get('errno', 0);
// 2 = no Zlib
// 3 = custom version detected
diff --git a/admin_configfiles.php b/admin_configfiles.php
index 2de1a5fd1c..51af09720f 100644
--- a/admin_configfiles.php
+++ b/admin_configfiles.php
@@ -93,14 +93,14 @@
asort($distributions_select);
}
- if ($distribution != "" && isset($_POST['finish'])) {
+ if ($distribution != "" && !empty(Request::post('finish'))) {
$valid_keys = ['http', 'dns', 'smtp', 'mail', 'antispam', 'ftp', 'system', 'distro'];
unset($_POST['finish']);
unset($_POST['csrf_token']);
- $params = $_POST;
+ $params = Request::postAll();
$params['distro'] = $distribution;
$params['system'] = [];
- foreach ($_POST['system'] as $sysdaemon) {
+ foreach (Request::post('system', []) as $sysdaemon) {
$params['system'][] = $sysdaemon;
}
// validate params
diff --git a/admin_cronjobs.php b/admin_cronjobs.php
index 3a77e69431..fc4a48d2d8 100644
--- a/admin_cronjobs.php
+++ b/admin_cronjobs.php
@@ -68,9 +68,9 @@
}
$result = json_decode($json_result, true)['data'];
if ($result['cronfile'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- Cronjobs::getLocal($userinfo, $_POST)->update();
+ Cronjobs::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
diff --git a/admin_customers.php b/admin_customers.php
index 72062ccaac..785145f92e 100644
--- a/admin_customers.php
+++ b/admin_customers.php
@@ -98,7 +98,7 @@
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_INFO, "switched user and is now '" . $destination_user . "'");
- $target = (isset($_GET['target']) ? $_GET['target'] : 'index');
+ $target = Request::get('target', 'index');
$redirect = "customer_" . $target . ".php";
if (!file_exists(Froxlor::getInstallDir() . "/" . $redirect)) {
$redirect = "customer_index.php";
@@ -119,7 +119,7 @@
}
$result = json_decode($json_result, true)['data'];
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
$json_result = Customers::getLocal($userinfo, [
'id' => $id
@@ -147,11 +147,11 @@
}
$result = json_decode($json_result, true)['data'];
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
$json_result = Customers::getLocal($userinfo, [
'id' => $id,
- 'delete_userfiles' => (isset($_POST['delete_userfiles']) ? (int)$_POST['delete_userfiles'] : 0)
+ 'delete_userfiles' => Request::post('delete_userfiles', 0)
])->delete();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
@@ -167,9 +167,9 @@
], $result['loginname']);
}
} elseif ($action == 'add') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- Customers::getLocal($userinfo, $_POST)->add();
+ Customers::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -243,9 +243,9 @@
$result = json_decode($json_result, true)['data'];
if ($result['loginname'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- Customers::getLocal($userinfo, $_POST)->update();
+ Customers::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
diff --git a/admin_domains.php b/admin_domains.php
index 4675e9fafe..722cf21b76 100644
--- a/admin_domains.php
+++ b/admin_domains.php
@@ -100,9 +100,9 @@
]);
if ($result['domain'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send' && $alias_check['count'] == 0) {
+ if (Request::post('send') == 'send' && $alias_check['count'] == 0) {
try {
- Domains::getLocal($userinfo, $_POST)->delete();
+ Domains::getLocal($userinfo, Request::postAll())->delete();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -113,7 +113,7 @@
} elseif ($alias_check['count'] > 0) {
Response::standardError('domains_cantdeletedomainwithaliases');
} else {
- HTML::askYesNo('admin_domain_reallydelete', $filename, [
+ HTML::askYesNoWithCheckbox('admin_domain_reallydelete', 'admin_customer_alsoremovemail', $filename, [
'id' => $id,
'page' => $page,
'action' => $action
@@ -121,9 +121,9 @@
}
}
} elseif ($action == 'add') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- Domains::getLocal($userinfo, $_POST)->add();
+ Domains::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -355,13 +355,13 @@
$usedips[] = $ipsresultrow['id_ipandports'];
}
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
// remove ssl ip/ports if set is empty
- if (!isset($_POST['ssl_ipandport']) || empty($_POST['ssl_ipandport'])) {
+ if (empty(Request::post('ssl_ipandport'))) {
$_POST['remove_ssl_ipandport'] = true;
}
- Domains::getLocal($userinfo, $_POST)->update();
+ Domains::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -572,13 +572,13 @@
}
}
} elseif ($action == 'jqGetCustomerPHPConfigs') {
- $customerid = intval($_POST['customerid']);
+ $customerid = intval(Request::post('customerid'));
$allowed_phpconfigs = Customer::getCustomerDetail($customerid, 'allowed_phpconfigs');
echo !empty($allowed_phpconfigs) ? $allowed_phpconfigs : json_encode([]);
exit();
} elseif ($action == 'jqSpeciallogfileNote') {
- $domainid = intval($_POST['id']);
- $newval = intval($_POST['newval']);
+ $domainid = intval(Request::post('id'));
+ $newval = intval(Request::post('newval'));
try {
$json_result = Domains::getLocal($userinfo, [
'id' => $domainid
@@ -594,9 +594,9 @@
echo 0;
exit();
} elseif ($action == 'import') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
- $separator = Validate::validate($_POST['separator'], 'separator');
- $offset = (int)Validate::validate($_POST['offset'], 'offset', "/[0-9]/i");
+ if (Request::post('send') == 'send') {
+ $separator = Validate::validate(Request::post('separator'), 'separator');
+ $offset = (int)Validate::validate(Request::post('offset'), 'offset', "/[0-9]/i");
$file_name = $_FILES['file']['tmp_name'];
@@ -636,9 +636,9 @@
]);
}
} elseif ($action == 'duplicate') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- Domains::getLocal($userinfo, $_POST)->duplicate();
+ Domains::getLocal($userinfo, Request::postAll())->duplicate();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
diff --git a/admin_index.php b/admin_index.php
index 0cca79fa50..4a2d3d4f18 100644
--- a/admin_index.php
+++ b/admin_index.php
@@ -55,7 +55,7 @@
$result = $result['switched_user'];
session_regenerate_id(true);
CurrentUser::setData($result);
- $target = (isset($_GET['target']) ? $_GET['target'] : 'index');
+ $target = Request::get('target', 'index');
$redirect = "admin_" . $target . ".php";
if (!file_exists(\Froxlor\Froxlor::getInstallDir() . "/" . $redirect)) {
$redirect = "admin_index.php";
@@ -111,7 +111,7 @@
$overview['number_domains'] = $number_domains['number_domains'];
- if ((isset($_GET['lookfornewversion']) && $_GET['lookfornewversion'] == 'yes') || (isset($lookfornewversion) && $lookfornewversion == 'yes')) {
+ if (Request::get('lookfornewversion') == 'yes' || (isset($lookfornewversion) && $lookfornewversion == 'yes')) {
try {
$json_result = Froxlor::getLocal($userinfo)->checkUpdate();
} catch (Exception $e) {
@@ -201,16 +201,16 @@
$languages = Language::getLanguages();
if (!empty($_POST)) {
- if ($_POST['send'] == 'changepassword') {
- $old_password = Validate::validate($_POST['old_password'], 'old password');
+ if (Request::post('send') == 'changepassword') {
+ $old_password = Validate::validate(Request::post('old_password'), 'old password');
if (!Crypt::validatePasswordLogin($userinfo, $old_password, TABLE_PANEL_ADMINS, 'adminid')) {
Response::standardError('oldpasswordnotcorrect');
}
try {
- $new_password = Crypt::validatePassword($_POST['new_password'], 'new password');
- $new_password_confirm = Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm');
+ $new_password = Crypt::validatePassword(Request::post('new_password'), 'new password');
+ $new_password_confirm = Crypt::validatePassword(Request::post('new_password_confirm'), 'new password confirm');
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -244,9 +244,9 @@
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'changed password');
Response::redirectTo($filename);
}
- } elseif ($_POST['send'] == 'changetheme') {
+ } elseif (Request::post('send') == 'changetheme') {
if (Settings::Get('panel.allow_theme_change_admin') == 1) {
- $theme = Validate::validate($_POST['theme'], 'theme');
+ $theme = Validate::validate(Request::post('theme'), 'theme');
try {
Admins::getLocal($userinfo, [
'id' => $userinfo['adminid'],
@@ -259,8 +259,8 @@
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, "changed his/her theme to '" . $theme . "'");
}
Response::redirectTo($filename);
- } elseif ($_POST['send'] == 'changelanguage') {
- $def_language = Validate::validate($_POST['def_language'], 'default language');
+ } elseif (Request::post('send') == 'changelanguage') {
+ $def_language = Validate::validate(Request::post('def_language'), 'default language');
if (isset($languages[$def_language])) {
try {
diff --git a/admin_ipsandports.php b/admin_ipsandports.php
index e8f796b3c4..905f1348c2 100644
--- a/admin_ipsandports.php
+++ b/admin_ipsandports.php
@@ -70,7 +70,7 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['id']) && $result['id'] == $id) {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
IpsAndPorts::getLocal($userinfo, [
'id' => $id
@@ -91,9 +91,9 @@
}
}
} elseif ($action == 'add') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- IpsAndPorts::getLocal($userinfo, $_POST)->add();
+ IpsAndPorts::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -119,9 +119,9 @@
$result = json_decode($json_result, true)['data'];
if ($result['ip'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- IpsAndPorts::getLocal($userinfo, $_POST)->update();
+ IpsAndPorts::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -141,9 +141,11 @@
}
}
} elseif ($action == 'jqCheckIP') {
- $ip = $_POST['ip'] ?? "";
- if ((filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE) == false) {
- // returns notice if private network detected so we can display it
+ $ip = Request::post('ip', '');
+ if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) {
+ echo json_encode('
'.lng('error.invalidip', [$ip]).'
');
+ } elseif (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE)) {
+ // returns notice if private network detected, so we can display it
echo json_encode(lng('admin.ipsandports.ipnote'));
} else {
echo 0;
diff --git a/admin_logger.php b/admin_logger.php
index 28fb963856..334b0c7218 100644
--- a/admin_logger.php
+++ b/admin_logger.php
@@ -31,6 +31,7 @@
use Froxlor\UI\HTML;
use Froxlor\UI\Listing;
use Froxlor\UI\Panel\UI;
+use Froxlor\UI\Request;
use Froxlor\UI\Response;
if ($page == 'log' && $userinfo['change_serversettings'] == '1') {
@@ -55,7 +56,7 @@
]
]);
} elseif ($action == 'truncate') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
SysLog::getLocal($userinfo, [
'min_to_keep' => 10
diff --git a/admin_message.php b/admin_message.php
index 34343acc88..4482345575 100644
--- a/admin_message.php
+++ b/admin_message.php
@@ -42,11 +42,11 @@
if ($action == '') {
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'viewed panel_message');
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
- if ($_POST['recipient'] == 0 && $userinfo['customers_see_all'] == '1') {
+ if (Request::post('send') == 'send') {
+ if (Request::post('recipient', -1) == 0 && $userinfo['customers_see_all'] == '1') {
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'sending messages to admins');
$result = Database::query('SELECT `name`, `email` FROM `' . TABLE_PANEL_ADMINS . "`");
- } elseif ($_POST['recipient'] == 1) {
+ } elseif (Request::post('recipient', -1) == 1) {
if ($userinfo['customers_see_all'] == '1') {
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'sending messages to ALL customers');
$result = Database::query('SELECT `firstname`, `name`, `company`, `email` FROM `' . TABLE_PANEL_CUSTOMERS . "`");
@@ -63,8 +63,8 @@
Response::standardError('norecipientsgiven');
}
- $subject = $_POST['subject'];
- $message = wordwrap($_POST['message'], 70);
+ $subject = Request::post('subject');
+ $message = wordwrap(Request::post('message'), 70);
if (!empty($message)) {
$mailcounter = 0;
@@ -107,7 +107,7 @@
}
}
} elseif ($action == 'showsuccess') {
- $sentitems = isset($_GET['sentitems']) ? (int)$_GET['sentitems'] : 0;
+ $sentitems = Request::get('sentitems', 0);
if ($sentitems == 0) {
$note_type = 'info';
diff --git a/admin_mysqlserver.php b/admin_mysqlserver.php
index 699a24414c..a213d0803f 100644
--- a/admin_mysqlserver.php
+++ b/admin_mysqlserver.php
@@ -70,7 +70,7 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['id']) && $result['id'] == $id) {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
MysqlServer::getLocal($userinfo, [
'id' => $id
@@ -91,9 +91,9 @@
}
}
} elseif ($action == 'add') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- MysqlServer::getLocal($userinfo, $_POST)->add();
+ MysqlServer::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -119,9 +119,9 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['id']) && $result['id'] == $id) {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- MysqlServer::getLocal($userinfo, $_POST)->update();
+ MysqlServer::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
diff --git a/admin_opcacheinfo.php b/admin_opcacheinfo.php
index eddace9e50..443a11d107 100644
--- a/admin_opcacheinfo.php
+++ b/admin_opcacheinfo.php
@@ -38,7 +38,7 @@
use Froxlor\UI\Response;
if ($action == 'reset' && function_exists('opcache_reset') && $userinfo['change_serversettings'] == '1') {
- if ($_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
opcache_reset();
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_INFO, "reset OPcache");
header('Location: ' . $linker->getLink([
diff --git a/admin_phpsettings.php b/admin_phpsettings.php
index 208692e203..13b14f3605 100644
--- a/admin_phpsettings.php
+++ b/admin_phpsettings.php
@@ -62,9 +62,9 @@
if ($action == 'add') {
if ((int)$userinfo['change_serversettings'] == 1) {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- PhpSettings::getLocal($userinfo, $_POST)->add();
+ PhpSettings::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -114,7 +114,7 @@
if ($result['id'] != 0 && $result['id'] == $id && (int)$userinfo['change_serversettings'] == 1 && $id != 1) // cannot delete the default php.config
{
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
PhpSettings::getLocal($userinfo, [
'id' => $id
@@ -148,9 +148,9 @@
$result = json_decode($json_result, true)['data'];
if ($result['id'] != 0 && $result['id'] == $id && (int)$userinfo['change_serversettings'] == 1) {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- PhpSettings::getLocal($userinfo, $_POST)->update();
+ PhpSettings::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -200,9 +200,9 @@
if ($action == 'add') {
if ((int)$userinfo['change_serversettings'] == 1) {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- FpmDaemons::getLocal($userinfo, $_POST)->add();
+ FpmDaemons::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -239,9 +239,9 @@
if ($result['id'] != 0 && $result['id'] == $id && (int)$userinfo['change_serversettings'] == 1 && $id != 1) // cannot delete the default php.config
{
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- FpmDaemons::getLocal($userinfo, $_POST)->delete();
+ FpmDaemons::getLocal($userinfo, Request::postAll())->delete();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -271,9 +271,9 @@
$result = json_decode($json_result, true)['data'];
if ($result['id'] != 0 && $result['id'] == $id && (int)$userinfo['change_serversettings'] == 1) {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- FpmDaemons::getLocal($userinfo, $_POST)->update();
+ FpmDaemons::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
diff --git a/admin_plans.php b/admin_plans.php
index f25ccd6f57..0a3bb09756 100644
--- a/admin_plans.php
+++ b/admin_plans.php
@@ -73,7 +73,7 @@
$result = json_decode($json_result, true)['data'];
if ($result['id'] != 0 && $result['id'] == $id && (int)$userinfo['adminid'] == $result['adminid']) {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
HostingPlans::getLocal($userinfo, [
'id' => $id
@@ -96,9 +96,9 @@
Response::standardError('nopermissionsorinvalidid');
}
} elseif ($action == 'add') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- HostingPlans::getLocal($userinfo, $_POST)->add();
+ HostingPlans::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -176,9 +176,9 @@
}
$result['allowed_phpconfigs'] = json_encode($result['allowed_phpconfigs']);
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- HostingPlans::getLocal($userinfo, $_POST)->update();
+ HostingPlans::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
diff --git a/admin_settings.php b/admin_settings.php
index 8d6fe4974c..9983b6b3b1 100644
--- a/admin_settings.php
+++ b/admin_settings.php
@@ -47,10 +47,10 @@
$settings_data = PhpHelper::loadConfigArrayDir('./actions/admin/settings/');
Settings::loadSettingsInto($settings_data);
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
- $_part = isset($_GET['part']) ? $_GET['part'] : '';
+ if (Request::post('send') == 'send') {
+ $_part = Request::get('part', '');
if ($_part == '') {
- $_part = isset($_POST['part']) ? $_POST['part'] : '';
+ $_part = Request::post('part', '');
}
if ($_part != '') {
@@ -69,12 +69,12 @@
}
// check if the session timeout is too low #815
- if (isset($_POST['session_sessiontimeout']) && $_POST['session_sessiontimeout'] < 60) {
+ if (!empty(Request::post('session_sessiontimeout')) && intval(Request::post('session_sessiontimeout', 0)) < 60) {
Response::standardError(['session_timeout', 'session_timeout_desc']);
}
try {
- if (Form::processForm($settings_data, $_POST, [
+ if (Form::processForm($settings_data, Request::postAll(), [
'filename' => $filename,
'action' => $action,
'page' => $page,
@@ -97,9 +97,9 @@
Response::dynamicError($e->getMessage(), $e->getCode());
}
} else {
- $_part = isset($_GET['part']) ? $_GET['part'] : '';
+ $_part = Request::get('part', '');
if ($_part == '') {
- $_part = isset($_POST['part']) ? $_POST['part'] : '';
+ $_part = Request::post('part', '');
}
$fields = Form::buildForm($settings_data, $_part);
@@ -140,7 +140,7 @@
'phpinfo' => $phpinfo
]);
} elseif ($page == 'rebuildconfigs' && $userinfo['change_serversettings'] == '1') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_INFO, "rebuild configfiles");
Cronjob::inserttask(TaskId::REBUILD_VHOST);
Cronjob::inserttask(TaskId::CREATE_QUOTA);
@@ -158,7 +158,7 @@
]);
}
} elseif ($page == 'updatecounters' && $userinfo['change_serversettings'] == '1') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_INFO, "updated resource-counters");
$updatecounters = User::updateCounters(true);
UI::view('user/resource-counter.html.twig', [
@@ -170,7 +170,7 @@
]);
}
} elseif ($page == 'wipecleartextmailpws' && $userinfo['change_serversettings'] == '1') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING, "wiped all cleartext mail passwords");
Database::query("UPDATE `" . TABLE_MAIL_USERS . "` SET `password` = '';");
Database::query("UPDATE `" . TABLE_PANEL_SETTINGS . "` SET `value` = '0' WHERE `settinggroup` = 'system' AND `varname` = 'mailpwcleartext'");
@@ -181,7 +181,7 @@
]);
}
} elseif ($page == 'wipequotas' && $userinfo['change_serversettings'] == '1') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_WARNING, "wiped all mailquotas");
// Set the quota to 0 which means unlimited
@@ -194,7 +194,7 @@
]);
}
} elseif ($page == 'enforcequotas' && $userinfo['change_serversettings'] == '1') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
// Fetch all accounts
$result_stmt = Database::query("SELECT `quota`, `customerid` FROM `" . TABLE_MAIL_USERS . "`");
@@ -233,9 +233,9 @@
}
} elseif ($page == 'integritycheck' && $userinfo['change_serversettings'] == '1') {
$integrity = new IntegrityCheck();
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
$integrity->fixAll();
- } elseif (isset($_GET['action']) && $_GET['action'] == "fix") {
+ } elseif (Request::get('action') == "fix") {
HTML::askYesNo('admin_integritycheck_reallyfix', $filename, [
'page' => $page
]);
@@ -273,7 +273,7 @@
Response::standardError('jsonextensionnotfound');
}
- if (isset($_GET['action']) && $_GET['action'] == "export") {
+ if (Request::get('action') == "export") {
// export
try {
$json_result = Froxlor::getLocal($userinfo)->exportSettings();
@@ -285,9 +285,9 @@
header('Content-type: application/json');
echo $json_export;
exit();
- } elseif (isset($_GET['action']) && $_GET['action'] == "import") {
+ } elseif (Request::get('action') == "import") {
// import
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
// get uploaded file
if (isset($_FILES["import_file"]["tmp_name"])) {
$imp_content = file_get_contents($_FILES["import_file"]["tmp_name"]);
@@ -330,8 +330,8 @@
$note_type = 'info';
$note_msg = lng('admin.smtptestnote');
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
- $test_addr = isset($_POST['test_addr']) ? $_POST['test_addr'] : null;
+ if (Request::post('send') == 'send') {
+ $test_addr = Request::post('test_addr');
// Initialize the mailingsystem
$testmail = new PHPMailer(true);
diff --git a/admin_templates.php b/admin_templates.php
index 7ae618bbac..07def60c35 100644
--- a/admin_templates.php
+++ b/admin_templates.php
@@ -192,7 +192,7 @@
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
if ($result['varname'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
$del_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_TEMPLATES . "`
WHERE `adminid` = :adminid
@@ -228,7 +228,7 @@
if (Database::num_rows() > 0) {
$row = $result_stmt->fetch(PDO::FETCH_ASSOC);
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
$del_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_TEMPLATES . "`
WHERE `adminid` = :adminid AND `id` = :id");
@@ -251,13 +251,13 @@
Response::standardError('templatenotfound');
}
} elseif ($action == 'add') {
- if (isset($_POST['prepare']) && $_POST['prepare'] == 'prepare') {
+ if (Request::post('prepare') == 'prepare') {
// email templates
- $language = htmlentities(Validate::validate($_POST['language'], 'language', '/^[^\r\n\0"\']+$/', 'nolanguageselect'));
+ $language = htmlentities(Validate::validate(Request::post('language'), 'language', '/^[^\r\n\0"\']+$/', 'nolanguageselect'));
if (!array_key_exists($language, $languages)) {
Response::standardError('templatelanguageinvalid');
}
- $template = Validate::validate($_POST['template'], 'template');
+ $template = Validate::validate(Request::post('template'), 'template');
$result_stmt = Database::prepare("
SELECT COUNT(*) as def FROM `" . TABLE_PANEL_TEMPLATES . "`
@@ -289,15 +289,15 @@
'formdata' => $template_add_data['template_add'],
'replacers' => $template_add_data['template_replacers']
]);
- } elseif (isset($_POST['send']) && $_POST['send'] == 'send' && !isset($_POST['filesend'])) {
+ } elseif (Request::post('send') == 'send' && empty(Request::post('filesend'))) {
// email templates
- $language = htmlentities(Validate::validate($_POST['language'], 'language', '/^[^\r\n\0"\']+$/', 'nolanguageselect'));
+ $language = htmlentities(Validate::validate(Request::post('language'), 'language', '/^[^\r\n\0"\']+$/', 'nolanguageselect'));
if (!array_key_exists($language, $languages)) {
Response::standardError('templatelanguageinvalid');
}
- $template = Validate::validate($_POST['template'], 'template');
- $subject = Validate::validate($_POST['subject'], 'subject', '/^[^\r\n\0]+$/', 'nosubjectcreate');
- $mailbody = Validate::validate($_POST['mailbody'], 'mailbody', '/^[^\0]+$/', 'nomailbodycreate');
+ $template = Validate::validate(Request::post('template'), 'template');
+ $subject = Validate::validate(Request::post('subject'), 'subject', '/^[^\r\n\0]+$/', 'nosubjectcreate');
+ $mailbody = Validate::validate(Request::post('mailbody'), 'mailbody', '/^[^\0]+$/', 'nomailbodycreate');
$templates = [];
$result_stmt = Database::prepare("
SELECT `varname` FROM `" . TABLE_PANEL_TEMPLATES . "`
@@ -347,10 +347,10 @@
'page' => $page
]);
}
- } elseif (isset($_POST['filesend']) && $_POST['filesend'] == 'filesend') {
+ } elseif (Request::post('filesend') == 'filesend') {
// file templates
- $template = Validate::validate($_POST['template'], 'template');
- $filecontent = Validate::validate($_POST['filecontent'], 'filecontent', '/^[^\0]+$/', 'filecontentnotset');
+ $template = Validate::validate(Request::post('template'), 'template');
+ $filecontent = Validate::validate(Request::post('filecontent'), 'filecontent', '/^[^\0]+$/', 'filecontentnotset');
$ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_TEMPLATES . "` SET
@@ -371,7 +371,7 @@
Response::redirectTo($filename, [
'page' => $page
]);
- } elseif (!isset($_GET['files'])) {
+ } elseif (empty(Request::get('files'))) {
// email templates
$add = false;
$language_options = [];
@@ -483,9 +483,9 @@
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
if ($result['varname'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
- $subject = Validate::validate($_POST['subject'], 'subject', '/^[^\r\n\0]+$/', 'nosubjectcreate');
- $mailbody = Validate::validate($_POST['mailbody'], 'mailbody', '/^[^\0]+$/', 'nomailbodycreate');
+ if (Request::post('send') == 'send') {
+ $subject = Validate::validate(Request::post('subject'), 'subject', '/^[^\r\n\0]+$/', 'nosubjectcreate');
+ $mailbody = Validate::validate(Request::post('mailbody'), 'mailbody', '/^[^\0]+$/', 'nomailbodycreate');
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_TEMPLATES . "` SET
@@ -551,8 +551,8 @@
$row = $result_stmt->fetch(PDO::FETCH_ASSOC);
// filetemplates
- if (isset($_POST['filesend']) && $_POST['filesend'] == 'filesend') {
- $filecontent = Validate::validate($_POST['filecontent'], 'filecontent', '/^[^\0]+$/', 'filecontentnotset');
+ if (Request::post('filesend') == 'filesend') {
+ $filecontent = Validate::validate(Request::post('filecontent'), 'filecontent', '/^[^\0]+$/', 'filecontentnotset');
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_TEMPLATES . "` SET
`value` = :value
diff --git a/admin_updates.php b/admin_updates.php
index d2c928aabc..0ae3e08c39 100644
--- a/admin_updates.php
+++ b/admin_updates.php
@@ -34,6 +34,7 @@
use Froxlor\Settings;
use Froxlor\System\Cronjob;
use Froxlor\UI\Panel\UI;
+use Froxlor\UI\Request;
use Froxlor\UI\Response;
use Froxlor\User;
@@ -48,8 +49,8 @@
$successful_update = false;
$message = '';
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
- if ((isset($_POST['update_preconfig']) && isset($_POST['update_changesagreed']) && intval($_POST['update_changesagreed']) != 0) || !isset($_POST['update_preconfig'])) {
+ if (Request::post('send') == 'send') {
+ if ((!empty(Request::post('update_preconfig')) && intval(Request::post('update_changesagreed', 0)) != 0) || empty(Request::post('update_preconfig'))) {
include_once Froxlor::getInstallDir() . 'install/updatesql.php';
User::updateCounters();
diff --git a/api_keys.php b/api_keys.php
index 1a5660906e..582cdb4b58 100644
--- a/api_keys.php
+++ b/api_keys.php
@@ -61,7 +61,7 @@
'section' => 'index',
'page' => $page
]);
-} elseif (isset($_POST['send']) && $_POST['send'] == 'send' && $action == 'deletesure' && $id > 0) {
+} elseif (Request::post('send') == 'send' && $action == 'deletesure' && $id > 0) {
$chk = (AREA == 'admin' && $userinfo['customers_see_all'] == '1') ? true : false;
if (AREA == 'customer') {
$chk_stmt = Database::prepare("
@@ -94,7 +94,7 @@
]);
}
} elseif ($action == 'add') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
$ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_API_KEYS . "` SET
`apikey` = :key, `secret` = :secret, `adminid` = :aid, `customerid` = :cid, `valid_until` = '-1', `allowed_from` = ''
diff --git a/composer.lock b/composer.lock
index 4a2234f292..929caf7142 100644
--- a/composer.lock
+++ b/composer.lock
@@ -201,16 +201,16 @@
},
{
"name": "league/commonmark",
- "version": "2.4.1",
+ "version": "2.4.2",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
- "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5"
+ "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/3669d6d5f7a47a93c08ddff335e6d945481a1dd5",
- "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5",
+ "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/91c24291965bd6d7c46c46a12ba7492f83b1cadf",
+ "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf",
"shasum": ""
},
"require": {
@@ -223,7 +223,7 @@
},
"require-dev": {
"cebe/markdown": "^1.0",
- "commonmark/cmark": "0.30.0",
+ "commonmark/cmark": "0.30.3",
"commonmark/commonmark.js": "0.30.0",
"composer/package-versions-deprecated": "^1.8",
"embed/embed": "^4.4",
@@ -233,10 +233,10 @@
"michelf/php-markdown": "^1.4 || ^2.0",
"nyholm/psr7": "^1.5",
"phpstan/phpstan": "^1.8.2",
- "phpunit/phpunit": "^9.5.21",
+ "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0",
"scrutinizer/ocular": "^1.8.1",
- "symfony/finder": "^5.3 | ^6.0",
- "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0",
+ "symfony/finder": "^5.3 | ^6.0 || ^7.0",
+ "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 || ^7.0",
"unleashedtech/php-coding-standard": "^3.1.1",
"vimeo/psalm": "^4.24.0 || ^5.0.0"
},
@@ -303,7 +303,7 @@
"type": "tidelift"
}
],
- "time": "2023-08-30T16:55:00+00:00"
+ "time": "2024-02-02T11:59:32+00:00"
},
{
"name": "league/config",
@@ -973,16 +973,16 @@
},
{
"name": "symfony/console",
- "version": "v5.4.32",
+ "version": "v5.4.39",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "c70df1ffaf23a8d340bded3cfab1b86752ad6ed7"
+ "reference": "f3e591c48688a0cfa1a3296205926c05e84b22b1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/c70df1ffaf23a8d340bded3cfab1b86752ad6ed7",
- "reference": "c70df1ffaf23a8d340bded3cfab1b86752ad6ed7",
+ "url": "https://api.github.com/repos/symfony/console/zipball/f3e591c48688a0cfa1a3296205926c05e84b22b1",
+ "reference": "f3e591c48688a0cfa1a3296205926c05e84b22b1",
"shasum": ""
},
"require": {
@@ -1052,7 +1052,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v5.4.32"
+ "source": "https://github.com/symfony/console/tree/v5.4.39"
},
"funding": [
{
@@ -1068,20 +1068,20 @@
"type": "tidelift"
}
],
- "time": "2023-11-18T18:23:04+00:00"
+ "time": "2024-04-18T08:26:06+00:00"
},
{
"name": "symfony/deprecation-contracts",
- "version": "v2.5.2",
+ "version": "v2.5.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
- "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
+ "reference": "80d075412b557d41002320b96a096ca65aa2c98d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
- "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/80d075412b557d41002320b96a096ca65aa2c98d",
+ "reference": "80d075412b557d41002320b96a096ca65aa2c98d",
"shasum": ""
},
"require": {
@@ -1119,7 +1119,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.3"
},
"funding": [
{
@@ -1135,20 +1135,20 @@
"type": "tidelift"
}
],
- "time": "2022-01-02T09:53:40+00:00"
+ "time": "2023-01-24T14:02:46+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
+ "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
- "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
+ "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
"shasum": ""
},
"require": {
@@ -1162,9 +1162,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1201,7 +1198,7 @@
"portable"
],
"support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
},
"funding": [
{
@@ -1217,20 +1214,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-iconv",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git",
- "reference": "6de50471469b8c9afc38164452ab2b6170ee71c1"
+ "reference": "cd4226d140ecd3d0f13d32ed0a4a095ffe871d2f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/6de50471469b8c9afc38164452ab2b6170ee71c1",
- "reference": "6de50471469b8c9afc38164452ab2b6170ee71c1",
+ "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/cd4226d140ecd3d0f13d32ed0a4a095ffe871d2f",
+ "reference": "cd4226d140ecd3d0f13d32ed0a4a095ffe871d2f",
"shasum": ""
},
"require": {
@@ -1244,9 +1241,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1284,7 +1278,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-iconv/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-iconv/tree/v1.29.0"
},
"funding": [
{
@@ -1300,20 +1294,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
- "reference": "875e90aeea2777b6f135677f618529449334a612"
+ "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612",
- "reference": "875e90aeea2777b6f135677f618529449334a612",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f",
+ "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f",
"shasum": ""
},
"require": {
@@ -1324,9 +1318,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1365,7 +1356,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0"
},
"funding": [
{
@@ -1381,20 +1372,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
- "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
+ "reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
- "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
+ "reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
"shasum": ""
},
"require": {
@@ -1405,9 +1396,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1449,7 +1437,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0"
},
"funding": [
{
@@ -1465,20 +1453,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "42292d99c55abe617799667f454222c54c60e229"
+ "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
- "reference": "42292d99c55abe617799667f454222c54c60e229",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
+ "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"shasum": ""
},
"require": {
@@ -1492,9 +1480,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1532,7 +1517,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
},
"funding": [
{
@@ -1548,20 +1533,20 @@
"type": "tidelift"
}
],
- "time": "2023-07-28T09:04:16+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-php72",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
- "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179"
+ "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179",
- "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179",
+ "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25",
+ "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25",
"shasum": ""
},
"require": {
@@ -1569,9 +1554,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1608,7 +1590,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-php72/tree/v1.29.0"
},
"funding": [
{
@@ -1624,20 +1606,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-php73",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php73.git",
- "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5"
+ "reference": "21bd091060673a1177ae842c0ef8fe30893114d2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5",
- "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5",
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2",
+ "reference": "21bd091060673a1177ae842c0ef8fe30893114d2",
"shasum": ""
},
"require": {
@@ -1645,9 +1627,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1687,7 +1666,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-php73/tree/v1.29.0"
},
"funding": [
{
@@ -1703,20 +1682,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-php80",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5"
+ "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
- "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
+ "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"shasum": ""
},
"require": {
@@ -1724,9 +1703,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1770,7 +1746,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0"
},
"funding": [
{
@@ -1786,20 +1762,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/service-contracts",
- "version": "v2.5.2",
+ "version": "v2.5.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c"
+ "reference": "a2329596ddc8fd568900e3fc76cba42489ecc7f3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
- "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a2329596ddc8fd568900e3fc76cba42489ecc7f3",
+ "reference": "a2329596ddc8fd568900e3fc76cba42489ecc7f3",
"shasum": ""
},
"require": {
@@ -1853,7 +1829,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v2.5.2"
+ "source": "https://github.com/symfony/service-contracts/tree/v2.5.3"
},
"funding": [
{
@@ -1869,20 +1845,20 @@
"type": "tidelift"
}
],
- "time": "2022-05-30T19:17:29+00:00"
+ "time": "2023-04-21T15:04:16+00:00"
},
{
"name": "symfony/string",
- "version": "v5.4.32",
+ "version": "v5.4.39",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "91bf4453d65d8231688a04376c3a40efe0770f04"
+ "reference": "495e71bae5862308051b9e63cc3e34078eed83ef"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/91bf4453d65d8231688a04376c3a40efe0770f04",
- "reference": "91bf4453d65d8231688a04376c3a40efe0770f04",
+ "url": "https://api.github.com/repos/symfony/string/zipball/495e71bae5862308051b9e63cc3e34078eed83ef",
+ "reference": "495e71bae5862308051b9e63cc3e34078eed83ef",
"shasum": ""
},
"require": {
@@ -1939,7 +1915,7 @@
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v5.4.32"
+ "source": "https://github.com/symfony/string/tree/v5.4.39"
},
"funding": [
{
@@ -1955,34 +1931,41 @@
"type": "tidelift"
}
],
- "time": "2023-11-26T13:43:46+00:00"
+ "time": "2024-04-18T08:26:06+00:00"
},
{
"name": "twig/twig",
- "version": "v3.8.0",
+ "version": "v3.10.2",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d"
+ "reference": "7aaed0b8311a557cc8c4047a71fd03153a00e755"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d",
- "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/7aaed0b8311a557cc8c4047a71fd03153a00e755",
+ "reference": "7aaed0b8311a557cc8c4047a71fd03153a00e755",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3",
"symfony/polyfill-php80": "^1.22"
},
"require-dev": {
"psr/container": "^1.0|^2.0",
- "symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0"
+ "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
},
"type": "library",
"autoload": {
+ "files": [
+ "src/Resources/core.php",
+ "src/Resources/debug.php",
+ "src/Resources/escaper.php",
+ "src/Resources/string_loader.php"
+ ],
"psr-4": {
"Twig\\": "src/"
}
@@ -2015,7 +1998,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
- "source": "https://github.com/twigphp/Twig/tree/v3.8.0"
+ "source": "https://github.com/twigphp/Twig/tree/v3.10.2"
},
"funding": [
{
@@ -2027,7 +2010,7 @@
"type": "tidelift"
}
],
- "time": "2023-11-21T18:54:41+00:00"
+ "time": "2024-05-14T06:04:16+00:00"
},
{
"name": "voku/anti-xss",
@@ -2293,16 +2276,16 @@
"packages-dev": [
{
"name": "composer/pcre",
- "version": "3.1.1",
+ "version": "3.1.3",
"source": {
"type": "git",
"url": "https://github.com/composer/pcre.git",
- "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9"
+ "reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9",
- "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9",
+ "url": "https://api.github.com/repos/composer/pcre/zipball/5b16e25a5355f1f3afdfc2f954a0a80aec4826a8",
+ "reference": "5b16e25a5355f1f3afdfc2f954a0a80aec4826a8",
"shasum": ""
},
"require": {
@@ -2344,7 +2327,7 @@
],
"support": {
"issues": "https://github.com/composer/pcre/issues",
- "source": "https://github.com/composer/pcre/tree/3.1.1"
+ "source": "https://github.com/composer/pcre/tree/3.1.3"
},
"funding": [
{
@@ -2360,20 +2343,20 @@
"type": "tidelift"
}
],
- "time": "2023-10-11T07:11:09+00:00"
+ "time": "2024-03-19T10:26:25+00:00"
},
{
"name": "composer/xdebug-handler",
- "version": "3.0.3",
+ "version": "3.0.5",
"source": {
"type": "git",
"url": "https://github.com/composer/xdebug-handler.git",
- "reference": "ced299686f41dce890debac69273b47ffe98a40c"
+ "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
- "reference": "ced299686f41dce890debac69273b47ffe98a40c",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef",
+ "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef",
"shasum": ""
},
"require": {
@@ -2384,7 +2367,7 @@
"require-dev": {
"phpstan/phpstan": "^1.0",
"phpstan/phpstan-strict-rules": "^1.1",
- "symfony/phpunit-bridge": "^6.0"
+ "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5"
},
"type": "library",
"autoload": {
@@ -2408,9 +2391,9 @@
"performance"
],
"support": {
- "irc": "irc://irc.freenode.org/composer",
+ "irc": "ircs://irc.libera.chat:6697/composer",
"issues": "https://github.com/composer/xdebug-handler/issues",
- "source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
+ "source": "https://github.com/composer/xdebug-handler/tree/3.0.5"
},
"funding": [
{
@@ -2426,7 +2409,7 @@
"type": "tidelift"
}
],
- "time": "2022-02-25T21:32:43+00:00"
+ "time": "2024-05-06T16:37:16+00:00"
},
{
"name": "doctrine/instantiator",
@@ -2559,25 +2542,27 @@
},
{
"name": "nikic/php-parser",
- "version": "v4.18.0",
+ "version": "v5.0.2",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999"
+ "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999",
- "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13",
+ "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13",
"shasum": ""
},
"require": {
+ "ext-ctype": "*",
+ "ext-json": "*",
"ext-tokenizer": "*",
- "php": ">=7.0"
+ "php": ">=7.4"
},
"require-dev": {
"ircmaxell/php-yacc": "^0.0.7",
- "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
},
"bin": [
"bin/php-parse"
@@ -2585,7 +2570,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.9-dev"
+ "dev-master": "5.0-dev"
}
},
"autoload": {
@@ -2609,9 +2594,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
- "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0"
+ "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2"
},
- "time": "2023-12-10T21:03:43+00:00"
+ "time": "2024-03-05T20:51:40+00:00"
},
{
"name": "pdepend/pdepend",
@@ -2678,20 +2663,21 @@
},
{
"name": "phar-io/manifest",
- "version": "2.0.3",
+ "version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/phar-io/manifest.git",
- "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
+ "reference": "54750ef60c58e43759730615a392c31c80e23176"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
- "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
+ "reference": "54750ef60c58e43759730615a392c31c80e23176",
"shasum": ""
},
"require": {
"ext-dom": "*",
+ "ext-libxml": "*",
"ext-phar": "*",
"ext-xmlwriter": "*",
"phar-io/version": "^3.0.1",
@@ -2732,9 +2718,15 @@
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
"support": {
"issues": "https://github.com/phar-io/manifest/issues",
- "source": "https://github.com/phar-io/manifest/tree/2.0.3"
+ "source": "https://github.com/phar-io/manifest/tree/2.0.4"
},
- "time": "2021-07-20T11:28:43+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/theseer",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-03T12:33:53+00:00"
},
{
"name": "phar-io/version",
@@ -2995,16 +2987,16 @@
},
{
"name": "phpstan/phpstan",
- "version": "1.10.50",
+ "version": "1.11.1",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
- "reference": "06a98513ac72c03e8366b5a0cb00750b487032e4"
+ "reference": "e524358f930e41a2b4cca1320e3b04fc26b39e0b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/06a98513ac72c03e8366b5a0cb00750b487032e4",
- "reference": "06a98513ac72c03e8366b5a0cb00750b487032e4",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e524358f930e41a2b4cca1320e3b04fc26b39e0b",
+ "reference": "e524358f930e41a2b4cca1320e3b04fc26b39e0b",
"shasum": ""
},
"require": {
@@ -3047,26 +3039,22 @@
{
"url": "https://github.com/phpstan",
"type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
- "type": "tidelift"
}
],
- "time": "2023-12-13T10:59:42+00:00"
+ "time": "2024-05-15T08:00:59+00:00"
},
{
"name": "phpunit/php-code-coverage",
- "version": "9.2.30",
+ "version": "9.2.31",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089"
+ "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089",
- "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965",
+ "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965",
"shasum": ""
},
"require": {
@@ -3123,7 +3111,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
- "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.30"
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.31"
},
"funding": [
{
@@ -3131,7 +3119,7 @@
"type": "github"
}
],
- "time": "2023-12-22T06:47:57+00:00"
+ "time": "2024-03-02T06:37:42+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -3376,16 +3364,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "9.6.15",
+ "version": "9.6.19",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1"
+ "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/05017b80304e0eb3f31d90194a563fd53a6021f1",
- "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1a54a473501ef4cdeaae4e06891674114d79db8",
+ "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8",
"shasum": ""
},
"require": {
@@ -3459,7 +3447,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.15"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.19"
},
"funding": [
{
@@ -3475,20 +3463,20 @@
"type": "tidelift"
}
],
- "time": "2023-12-01T16:55:19+00:00"
+ "time": "2024-04-05T04:35:58+00:00"
},
{
"name": "sebastian/cli-parser",
- "version": "1.0.1",
+ "version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/cli-parser.git",
- "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
+ "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
- "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
+ "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
"shasum": ""
},
"require": {
@@ -3523,7 +3511,7 @@
"homepage": "https://github.com/sebastianbergmann/cli-parser",
"support": {
"issues": "https://github.com/sebastianbergmann/cli-parser/issues",
- "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
+ "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2"
},
"funding": [
{
@@ -3531,7 +3519,7 @@
"type": "github"
}
],
- "time": "2020-09-28T06:08:49+00:00"
+ "time": "2024-03-02T06:27:43+00:00"
},
{
"name": "sebastian/code-unit",
@@ -3777,16 +3765,16 @@
},
{
"name": "sebastian/diff",
- "version": "4.0.5",
+ "version": "4.0.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131"
+ "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
- "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc",
+ "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc",
"shasum": ""
},
"require": {
@@ -3831,7 +3819,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
- "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5"
+ "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6"
},
"funding": [
{
@@ -3839,7 +3827,7 @@
"type": "github"
}
],
- "time": "2023-05-07T05:35:17+00:00"
+ "time": "2024-03-02T06:30:58+00:00"
},
{
"name": "sebastian/environment",
@@ -3906,16 +3894,16 @@
},
{
"name": "sebastian/exporter",
- "version": "4.0.5",
+ "version": "4.0.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d"
+ "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
- "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72",
+ "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72",
"shasum": ""
},
"require": {
@@ -3971,7 +3959,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues",
- "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5"
+ "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6"
},
"funding": [
{
@@ -3979,20 +3967,20 @@
"type": "github"
}
],
- "time": "2022-09-14T06:03:37+00:00"
+ "time": "2024-03-02T06:33:00+00:00"
},
{
"name": "sebastian/global-state",
- "version": "5.0.6",
+ "version": "5.0.7",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "bde739e7565280bda77be70044ac1047bc007e34"
+ "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34",
- "reference": "bde739e7565280bda77be70044ac1047bc007e34",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9",
+ "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9",
"shasum": ""
},
"require": {
@@ -4035,7 +4023,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
- "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6"
+ "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7"
},
"funding": [
{
@@ -4043,7 +4031,7 @@
"type": "github"
}
],
- "time": "2023-08-02T09:26:13+00:00"
+ "time": "2024-03-02T06:35:11+00:00"
},
{
"name": "sebastian/lines-of-code",
@@ -4341,16 +4329,16 @@
},
{
"name": "sebastian/resource-operations",
- "version": "3.0.3",
+ "version": "3.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/resource-operations.git",
- "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
+ "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
- "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
+ "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
"shasum": ""
},
"require": {
@@ -4362,7 +4350,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-main": "3.0-dev"
}
},
"autoload": {
@@ -4383,8 +4371,7 @@
"description": "Provides a list of PHP built-in functions that operate on resources",
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
"support": {
- "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
- "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
+ "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4"
},
"funding": [
{
@@ -4392,7 +4379,7 @@
"type": "github"
}
],
- "time": "2020-09-28T06:45:17+00:00"
+ "time": "2024-03-14T16:00:52+00:00"
},
{
"name": "sebastian/type",
@@ -4505,16 +4492,16 @@
},
{
"name": "squizlabs/php_codesniffer",
- "version": "3.8.0",
+ "version": "3.9.2",
"source": {
"type": "git",
"url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
- "reference": "5805f7a4e4958dbb5e944ef1e6edae0a303765e7"
+ "reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5805f7a4e4958dbb5e944ef1e6edae0a303765e7",
- "reference": "5805f7a4e4958dbb5e944ef1e6edae0a303765e7",
+ "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/aac1f6f347a5c5ac6bc98ad395007df00990f480",
+ "reference": "aac1f6f347a5c5ac6bc98ad395007df00990f480",
"shasum": ""
},
"require": {
@@ -4524,11 +4511,11 @@
"php": ">=5.4.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4"
},
"bin": [
- "bin/phpcs",
- "bin/phpcbf"
+ "bin/phpcbf",
+ "bin/phpcs"
],
"type": "library",
"extra": {
@@ -4581,20 +4568,20 @@
"type": "open_collective"
}
],
- "time": "2023-12-08T12:32:31+00:00"
+ "time": "2024-04-23T20:25:34+00:00"
},
{
"name": "symfony/config",
- "version": "v5.4.31",
+ "version": "v5.4.39",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
- "reference": "dd5ea39de228813aba0c23c3a4153da2a4cf3cd9"
+ "reference": "62cec4a067931552624a9962002c210c502d42fd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/dd5ea39de228813aba0c23c3a4153da2a4cf3cd9",
- "reference": "dd5ea39de228813aba0c23c3a4153da2a4cf3cd9",
+ "url": "https://api.github.com/repos/symfony/config/zipball/62cec4a067931552624a9962002c210c502d42fd",
+ "reference": "62cec4a067931552624a9962002c210c502d42fd",
"shasum": ""
},
"require": {
@@ -4644,7 +4631,7 @@
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/config/tree/v5.4.31"
+ "source": "https://github.com/symfony/config/tree/v5.4.39"
},
"funding": [
{
@@ -4660,20 +4647,20 @@
"type": "tidelift"
}
],
- "time": "2023-11-09T08:22:43+00:00"
+ "time": "2024-04-18T08:26:06+00:00"
},
{
"name": "symfony/dependency-injection",
- "version": "v5.4.33",
+ "version": "v5.4.39",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
- "reference": "14969a558cd6382b2a12b14b20ef9a851a02da79"
+ "reference": "5b4505f2afbe1d11d43a3917d0c1c178a38f6f19"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/14969a558cd6382b2a12b14b20ef9a851a02da79",
- "reference": "14969a558cd6382b2a12b14b20ef9a851a02da79",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/5b4505f2afbe1d11d43a3917d0c1c178a38f6f19",
+ "reference": "5b4505f2afbe1d11d43a3917d0c1c178a38f6f19",
"shasum": ""
},
"require": {
@@ -4733,7 +4720,7 @@
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/dependency-injection/tree/v5.4.33"
+ "source": "https://github.com/symfony/dependency-injection/tree/v5.4.39"
},
"funding": [
{
@@ -4749,27 +4736,28 @@
"type": "tidelift"
}
],
- "time": "2023-11-30T08:15:37+00:00"
+ "time": "2024-04-18T08:26:06+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v5.4.25",
+ "version": "v5.4.39",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "0ce3a62c9579a53358d3a7eb6b3dfb79789a6364"
+ "reference": "e6edd875d5d39b03de51f3c3951148cfa79a4d12"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/0ce3a62c9579a53358d3a7eb6b3dfb79789a6364",
- "reference": "0ce3a62c9579a53358d3a7eb6b3dfb79789a6364",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/e6edd875d5d39b03de51f3c3951148cfa79a4d12",
+ "reference": "e6edd875d5d39b03de51f3c3951148cfa79a4d12",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.8",
- "symfony/polyfill-php80": "^1.16"
+ "symfony/polyfill-php80": "^1.16",
+ "symfony/process": "^5.4|^6.4"
},
"type": "library",
"autoload": {
@@ -4797,7 +4785,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/filesystem/tree/v5.4.25"
+ "source": "https://github.com/symfony/filesystem/tree/v5.4.39"
},
"funding": [
{
@@ -4813,20 +4801,20 @@
"type": "tidelift"
}
],
- "time": "2023-05-31T13:04:02+00:00"
+ "time": "2024-04-18T08:26:06+00:00"
},
{
"name": "symfony/polyfill-php81",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
- "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b"
+ "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b",
- "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b",
+ "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d",
+ "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d",
"shasum": ""
},
"require": {
@@ -4834,9 +4822,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -4876,7 +4861,69 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-01-29T20:11:03+00:00"
+ },
+ {
+ "name": "symfony/process",
+ "version": "v5.4.39",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/process.git",
+ "reference": "85a554acd7c28522241faf2e97b9541247a0d3d5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/process/zipball/85a554acd7c28522241faf2e97b9541247a0d3d5",
+ "reference": "85a554acd7c28522241faf2e97b9541247a0d3d5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-php80": "^1.16"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Process\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Executes commands in sub-processes",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/process/tree/v5.4.39"
},
"funding": [
{
@@ -4892,20 +4939,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-04-18T08:26:06+00:00"
},
{
"name": "theseer/tokenizer",
- "version": "1.2.2",
+ "version": "1.2.3",
"source": {
"type": "git",
"url": "https://github.com/theseer/tokenizer.git",
- "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96"
+ "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
- "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
+ "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
"shasum": ""
},
"require": {
@@ -4934,7 +4981,7 @@
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"support": {
"issues": "https://github.com/theseer/tokenizer/issues",
- "source": "https://github.com/theseer/tokenizer/tree/1.2.2"
+ "source": "https://github.com/theseer/tokenizer/tree/1.2.3"
},
"funding": [
{
@@ -4942,7 +4989,7 @@
"type": "github"
}
],
- "time": "2023-11-20T00:12:19+00:00"
+ "time": "2024-03-03T12:36:25+00:00"
}
],
"aliases": [],
@@ -4972,5 +5019,5 @@
"platform-dev": {
"ext-pcntl": "*"
},
- "plugin-api-version": "2.3.0"
+ "plugin-api-version": "2.6.0"
}
diff --git a/customer_domains.php b/customer_domains.php
index 94add191dc..c87105c0fc 100644
--- a/customer_domains.php
+++ b/customer_domains.php
@@ -26,7 +26,7 @@
const AREA = 'customer';
require __DIR__ . '/lib/init.php';
-use Froxlor\Api\Commands\SubDomains as SubDomains;
+use Froxlor\Api\Commands\SubDomains;
use Froxlor\CurrentUser;
use Froxlor\Database\Database;
use Froxlor\Domain\Domain;
@@ -72,7 +72,7 @@
}
$actions_links[] = [
- 'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/domains/',
+ 'href' => \Froxlor\Froxlor::getDocsUrl() . 'user-guide/domains/',
'target' => '_blank',
'icon' => 'fa-solid fa-circle-info',
'class' => 'btn-outline-secondary'
@@ -106,9 +106,9 @@
]);
if (isset($result['parentdomainid']) && $result['parentdomainid'] != '0' && $alias_check['count'] == 0) {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- SubDomains::getLocal($userinfo, $_POST)->delete();
+ SubDomains::getLocal($userinfo, Request::postAll())->delete();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -127,9 +127,9 @@
}
} elseif ($action == 'add') {
if ($userinfo['subdomains_used'] < $userinfo['subdomains'] || $userinfo['subdomains'] == '-1') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- SubDomains::getLocal($userinfo, $_POST)->add();
+ SubDomains::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -248,9 +248,9 @@
Response::standardError('domaincannotbeedited', $result['domain']);
}
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- SubDomains::getLocal($userinfo, $_POST)->update();
+ SubDomains::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -395,8 +395,8 @@
Response::standardError('domains_canteditdomain');
}
} elseif ($action == 'jqSpeciallogfileNote') {
- $domainid = intval($_POST['id']);
- $newval = intval($_POST['newval']);
+ $domainid = intval(Request::post('id'));
+ $newval = intval(Request::post('newval'));
try {
$json_result = SubDomains::getLocal($userinfo, [
'id' => $domainid
diff --git a/customer_email.php b/customer_email.php
index 8a5616deef..dc55aed083 100644
--- a/customer_email.php
+++ b/customer_email.php
@@ -30,6 +30,7 @@
use Froxlor\Api\Commands\EmailDomains;
use Froxlor\Api\Commands\EmailForwarders;
use Froxlor\Api\Commands\Emails;
+use Froxlor\Cron\Mail\Rspamd;
use Froxlor\CurrentUser;
use Froxlor\Database\Database;
use Froxlor\FroxlorLogger;
@@ -76,7 +77,7 @@
}
$actions_links[] = [
- 'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/emails/',
+ 'href' => \Froxlor\Froxlor::getDocsUrl() . 'user-guide/emails/',
'target' => '_blank',
'icon' => 'fa-solid fa-circle-info',
'class' => 'btn-outline-secondary'
@@ -138,7 +139,7 @@
];
}
$actions_links[] = [
- 'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/emails/',
+ 'href' => \Froxlor\Froxlor::getDocsUrl() . 'user-guide/emails/',
'target' => '_blank',
'icon' => 'fa-solid fa-circle-info',
'class' => 'btn-outline-secondary'
@@ -160,11 +161,11 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['email']) && $result['email'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
Emails::getLocal($userinfo, [
'id' => $id,
- 'delete_userfiles' => ($_POST['delete_userfiles'] ?? 0)
+ 'delete_userfiles' => Request::post('delete_userfiles', 0)
])->delete();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
@@ -187,9 +188,9 @@
}
} elseif ($action == 'add') {
if ($userinfo['emails_used'] < $userinfo['emails'] || $userinfo['emails'] == '-1') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- $json_result = Emails::getLocal($userinfo, $_POST)->add();
+ $json_result = Emails::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -244,12 +245,12 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['email']) && $result['email'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
Emails::getLocal($userinfo, [
'id' => $id,
- 'spam_tag_level' => $_POST['spam_tag_level'] ?? \Froxlor\Cron\Mail\Rspamd::DEFAULT_MARK_LVL,
- 'spam_kill_level' => $_POST['spam_kill_level'] ?? \Froxlor\Cron\Mail\Rspamd::DEFAULT_REJECT_LVL
+ 'spam_tag_level' => Request::post('spam_tag_level', Rspamd::DEFAULT_MARK_LVL),
+ 'spam_kill_level' => Request::post('spam_kill_level', Rspamd::DEFAULT_REJECT_LVL)
])->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
@@ -386,9 +387,9 @@
}
$result = json_decode($json_result, true)['data'];
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- EmailAccounts::getLocal($userinfo, $_POST)->add();
+ EmailAccounts::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -457,9 +458,9 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['popaccountid']) && $result['popaccountid'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- EmailAccounts::getLocal($userinfo, $_POST)->update();
+ EmailAccounts::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -516,9 +517,9 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['popaccountid']) && $result['popaccountid'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- EmailAccounts::getLocal($userinfo, $_POST)->update();
+ EmailAccounts::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -575,9 +576,9 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['popaccountid']) && $result['popaccountid'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- EmailAccounts::getLocal($userinfo, $_POST)->delete();
+ EmailAccounts::getLocal($userinfo, Request::postAll())->delete();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -611,9 +612,9 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['email']) && $result['email'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- EmailForwarders::getLocal($userinfo, $_POST)->add();
+ EmailForwarders::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -673,22 +674,15 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['destination']) && $result['destination'] != '') {
- if (isset($_POST['forwarderid'])) {
- $forwarderid = intval($_POST['forwarderid']);
- } elseif (isset($_GET['forwarderid'])) {
- $forwarderid = intval($_GET['forwarderid']);
- } else {
- $forwarderid = 0;
- }
-
+ $forwarderid = Request::any('forwarderid', 0);
$result['destination'] = explode(' ', $result['destination']);
if (isset($result['destination'][$forwarderid]) && $result['email'] != $result['destination'][$forwarderid]) {
$forwarder = $result['destination'][$forwarderid];
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- EmailForwarders::getLocal($userinfo, $_POST)->delete();
+ EmailForwarders::getLocal($userinfo, Request::postAll())->delete();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
diff --git a/customer_extras.php b/customer_extras.php
index b7e91e334c..0656241d8d 100644
--- a/customer_extras.php
+++ b/customer_extras.php
@@ -75,7 +75,7 @@
];
$actions_links[] = [
- 'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/extras/',
+ 'href' => \Froxlor\Froxlor::getDocsUrl() . 'user-guide/extras/',
'target' => '_blank',
'icon' => 'fa-solid fa-circle-info',
'class' => 'btn-outline-secondary'
@@ -97,9 +97,9 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['username']) && $result['username'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- DirProtections::getLocal($userinfo, $_POST)->delete();
+ DirProtections::getLocal($userinfo, Request::postAll())->delete();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -119,9 +119,9 @@
}
}
} elseif ($action == 'add') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- DirProtections::getLocal($userinfo, $_POST)->add();
+ DirProtections::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -149,9 +149,9 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['username']) && $result['username'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- DirProtections::getLocal($userinfo, $_POST)->update();
+ DirProtections::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -200,7 +200,7 @@
];
$actions_links[] = [
- 'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/extras/',
+ 'href' => \Froxlor\Froxlor::getDocsUrl() . 'user-guide/extras/',
'target' => '_blank',
'icon' => 'fa-solid fa-circle-info',
'class' => 'btn-outline-secondary'
@@ -222,9 +222,9 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['customerid']) && $result['customerid'] != '' && $result['customerid'] == $userinfo['customerid']) {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- DirOptions::getLocal($userinfo, $_POST)->delete();
+ DirOptions::getLocal($userinfo, Request::postAll())->delete();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -240,9 +240,9 @@
}
}
} elseif ($action == 'add') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- DirOptions::getLocal($userinfo, $_POST)->add();
+ DirOptions::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -271,9 +271,9 @@
$result = json_decode($json_result, true)['data'];
if ((isset($result['customerid'])) && ($result['customerid'] != '') && ($result['customerid'] == $userinfo['customerid'])) {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- DirOptions::getLocal($userinfo, $_POST)->update();
+ DirOptions::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -306,10 +306,10 @@
if (Settings::Get('system.exportenabled') == 1) {
if ($action == 'abort') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
$log->logAction(FroxlorLogger::USR_ACTION, LOG_NOTICE, "customer_extras::export - aborted scheduled data export job");
try {
- DataDump::getLocal($userinfo, $_POST)->delete();
+ DataDump::getLocal($userinfo, Request::postAll())->delete();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -336,9 +336,9 @@
Response::dynamicError($e->getMessage());
}
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- DataDump::getLocal($userinfo, $_POST)->add();
+ DataDump::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -349,7 +349,7 @@
$actions_links = [
[
- 'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/extras/',
+ 'href' => \Froxlor\Froxlor::getDocsUrl() . 'user-guide/extras/',
'target' => '_blank',
'icon' => 'fa-solid fa-circle-info',
'class' => 'btn-outline-secondary'
diff --git a/customer_ftp.php b/customer_ftp.php
index 0552140528..05e169237a 100644
--- a/customer_ftp.php
+++ b/customer_ftp.php
@@ -65,7 +65,7 @@
];
}
$actions_links[] = [
- 'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/ftp-accounts/',
+ 'href' => \Froxlor\Froxlor::getDocsUrl() . 'user-guide/ftp-accounts/',
'target' => '_blank',
'icon' => 'fa-solid fa-circle-info',
'class' => 'btn-outline-secondary'
@@ -87,9 +87,9 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['username']) && $result['username'] != $userinfo['loginname']) {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- Ftps::getLocal($userinfo, $_POST)->delete();
+ Ftps::getLocal($userinfo, Request::postAll())->delete();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -108,9 +108,9 @@
}
} elseif ($action == 'add') {
if ($userinfo['ftps_used'] < $userinfo['ftps'] || $userinfo['ftps'] == '-1') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- Ftps::getLocal($userinfo, $_POST)->add();
+ Ftps::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -164,9 +164,9 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['username']) && $result['username'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- Ftps::getLocal($userinfo, $_POST)->update();
+ Ftps::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
diff --git a/customer_index.php b/customer_index.php
index 70cb2ae34c..4a863bc843 100644
--- a/customer_index.php
+++ b/customer_index.php
@@ -38,6 +38,7 @@
use Froxlor\System\Cronjob;
use Froxlor\System\Crypt;
use Froxlor\UI\Panel\UI;
+use Froxlor\UI\Request;
use Froxlor\UI\Response;
use Froxlor\Validate\Validate;
@@ -55,7 +56,7 @@
$result = $result['switched_user'];
session_regenerate_id(true);
CurrentUser::setData($result);
- $target = (isset($_GET['target']) ? $_GET['target'] : 'index');
+ $target = Request::get('target', 'index');
$redirect = "admin_" . $target . ".php";
if (!file_exists(Froxlor::getInstallDir() . "/" . $redirect)) {
$redirect = "admin_index.php";
@@ -141,16 +142,16 @@
$languages = Language::getLanguages();
if (!empty($_POST)) {
- if ($_POST['send'] == 'changepassword') {
- $old_password = Validate::validate($_POST['old_password'], 'old password');
+ if (Request::post('send') == 'changepassword') {
+ $old_password = Validate::validate(Request::post('old_password'), 'old password');
if (!Crypt::validatePasswordLogin($userinfo, $old_password, TABLE_PANEL_CUSTOMERS, 'customerid')) {
Response::standardError('oldpasswordnotcorrect');
}
try {
- $new_password = Crypt::validatePassword($_POST['new_password'], 'new password');
- $new_password_confirm = Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm');
+ $new_password = Crypt::validatePassword(Request::post('new_password'), 'new password');
+ $new_password_confirm = Crypt::validatePassword(Request::post('new_password_confirm'), 'new password confirm');
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -185,7 +186,7 @@
$log->logAction(FroxlorLogger::USR_ACTION, LOG_NOTICE, 'changed password');
// Update ftp password
- if (isset($_POST['change_main_ftp']) && $_POST['change_main_ftp'] == 'true') {
+ if (Request::post('change_main_ftp') == 'true') {
$cryptPassword = Crypt::makeCryptPassword($new_password);
$stmt = Database::prepare("UPDATE `" . TABLE_FTP_USERS . "`
SET `password` = :password
@@ -201,7 +202,7 @@
}
// Update statistics password
- if (isset($_POST['change_stats']) && $_POST['change_stats'] == 'true') {
+ if (Request::post('change_stats') == 'true') {
$new_stats_password = Crypt::makeCryptPassword($new_password, true);
$stmt = Database::prepare("UPDATE `" . TABLE_PANEL_HTPASSWDS . "`
@@ -218,7 +219,7 @@
}
// Update global myqsl user password
- if ($userinfo['mysqls'] != 0 && isset($_POST['change_global_mysql']) && $_POST['change_global_mysql'] == 'true') {
+ if ($userinfo['mysqls'] != 0 && Request::post('change_global_mysql') == 'true') {
$allowed_mysqlservers = json_decode($userinfo['allowed_mysqlserver'] ?? '[]', true);
foreach ($allowed_mysqlservers as $dbserver) {
// require privileged access for target db-server
@@ -227,7 +228,12 @@
$dbm = new DbManager($log);
// give permission to the user on every access-host we have
foreach (array_map('trim', explode(',', Settings::Get('system.mysql_access_host'))) as $mysql_access_host) {
- $dbm->getManager()->grantPrivilegesTo($userinfo['loginname'], $new_password, $mysql_access_host, false, true);
+ if ($dbm->getManager()->userExistsOnHost($userinfo['loginname'], $mysql_access_host)) {
+ $dbm->getManager()->grantPrivilegesTo($userinfo['loginname'], $new_password, $mysql_access_host, false, true);
+ } else {
+ // create global mysql user if not exists
+ $dbm->getManager()->grantPrivilegesTo($userinfo['loginname'], $new_password, $mysql_access_host, false, false, true);
+ }
}
$dbm->getManager()->flushPrivileges();
}
@@ -235,9 +241,9 @@
Response::redirectTo($filename);
}
- } elseif ($_POST['send'] == 'changetheme') {
+ } elseif (Request::post('send') == 'changetheme') {
if (Settings::Get('panel.allow_theme_change_customer') == 1) {
- $theme = Validate::validate($_POST['theme'], 'theme');
+ $theme = Validate::validate(Request::post('theme'), 'theme');
try {
Customers::getLocal($userinfo, [
'id' => $userinfo['customerid'],
@@ -250,8 +256,8 @@
$log->logAction(FroxlorLogger::USR_ACTION, LOG_NOTICE, "changed default theme to '" . $theme . "'");
}
Response::redirectTo($filename);
- } elseif ($_POST['send'] == 'changelanguage') {
- $def_language = Validate::validate($_POST['def_language'], 'default language');
+ } elseif (Request::post('send') == 'changelanguage') {
+ $def_language = Validate::validate(Request::post('def_language'), 'default language');
if (isset($languages[$def_language])) {
try {
Customers::getLocal($userinfo, [
diff --git a/customer_mysql.php b/customer_mysql.php
index df044a640f..e2372448a8 100644
--- a/customer_mysql.php
+++ b/customer_mysql.php
@@ -89,7 +89,7 @@
}
$actions_links[] = [
- 'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/databases/',
+ 'href' => \Froxlor\Froxlor::getDocsUrl() . 'user-guide/databases/',
'target' => '_blank',
'icon' => 'fa-solid fa-circle-info',
'class' => 'btn-outline-secondary'
@@ -123,9 +123,9 @@
$result['dbserver'] = 0;
}
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- Mysqls::getLocal($userinfo, $_POST)->delete();
+ Mysqls::getLocal($userinfo, Request::postAll())->delete();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -146,9 +146,9 @@
}
} elseif ($action == 'add') {
if ($userinfo['mysqls_used'] < $userinfo['mysqls'] || $userinfo['mysqls'] == '-1') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- Mysqls::getLocal($userinfo, $_POST)->add();
+ Mysqls::getLocal($userinfo, Request::postAll())->add();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -186,9 +186,9 @@
$result = json_decode($json_result, true)['data'];
if (isset($result['databasename']) && $result['databasename'] != '') {
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
try {
- $json_result = Mysqls::getLocal($userinfo, $_POST)->update();
+ $json_result = Mysqls::getLocal($userinfo, Request::postAll())->update();
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
}
@@ -223,9 +223,9 @@
Response::dynamicError('No permission');
}
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
- $new_password = Crypt::validatePassword($_POST['mysql_password']);
+ $new_password = Crypt::validatePassword(Request::post('mysql_password'));
foreach ($allowed_mysqlservers as $dbserver) {
// require privileged access for target db-server
Database::needRoot(true, $dbserver, false);
diff --git a/dns_editor.php b/dns_editor.php
index 9d2e41bb2c..ee03f6dca3 100644
--- a/dns_editor.php
+++ b/dns_editor.php
@@ -30,6 +30,7 @@
use Froxlor\Api\Commands\DomainZones;
use Froxlor\Dns\Dns;
+use Froxlor\Settings;
use Froxlor\UI\Collection;
use Froxlor\UI\HTML;
use Froxlor\UI\Listing;
@@ -42,11 +43,11 @@
$domain_id = (int)Request::any('domain_id');
-$record = isset($_POST['dns_record']) ? trim($_POST['dns_record']) : null;
-$type = isset($_POST['dns_type']) ? $_POST['dns_type'] : 'A';
-$prio = isset($_POST['dns_mxp']) ? (int)$_POST['dns_mxp'] : null;
-$content = isset($_POST['dns_content']) ? trim($_POST['dns_content']) : null;
-$ttl = isset($_POST['dns_ttl']) ? (int)$_POST['dns_ttl'] : 18000;
+$record = Request::post('dns_record');
+$type = Request::post('dns_type', 'A');
+$prio = Request::post('dns_mxp');
+$content = Request::post('dns_content');
+$ttl = (int)Request::post('dns_ttl', Settings::get('system.defaultttl'));
// get domain-name
$domain = Dns::getAllowedDomainEntry($domain_id, AREA, $userinfo);
@@ -71,7 +72,7 @@
$errors = str_replace("\n", "
", $e->getMessage());
}
} elseif ($action == 'delete') {
- $entry_id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
+ $entry_id = (int)Request::get('id', 0);
HTML::askYesNo('dnsentry_reallydelete', $filename, [
'id' => $entry_id,
'domain_id' => $domain_id,
@@ -82,9 +83,9 @@
'page' => $page,
'domain_id' => $domain_id
]);
-} elseif (isset($_POST['send']) && $_POST['send'] == 'send' && $action == 'deletesure' && !empty($_POST)) {
- $entry_id = isset($_POST['id']) ? (int)$_POST['id'] : 0;
- $domain_id = isset($_POST['domain_id']) ? (int)$_POST['domain_id'] : 0;
+} elseif (Request::post('send') == 'send' && $action == 'deletesure' && !empty($_POST)) {
+ $entry_id = (int)Request::post('id', 0);
+ $domain_id = (int)Request::post('domain_id', 0);
// remove entry
if ($entry_id > 0 && $domain_id > 0) {
try {
diff --git a/error_report.php b/error_report.php
index 0f2347452f..6e0c581378 100644
--- a/error_report.php
+++ b/error_report.php
@@ -77,7 +77,7 @@
$mail_html = nl2br($mail_body);
// send actual report to dev-team
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ if (Request::post('send') == 'send') {
// send mail and say thanks
$_mailerror = false;
try {
diff --git a/index.php b/index.php
index ee63cbde29..c2f6d9116c 100644
--- a/index.php
+++ b/index.php
@@ -54,7 +54,7 @@
Response::redirectTo('index.php');
exit();
}
- $smessage = isset($_GET['showmessage']) ? (int)$_GET['showmessage'] : 0;
+ $smessage = (int)Request::get('showmessage', 0);
$message = "";
if ($smessage > 0) {
$message = lng('error.2fa_wrongcode');
@@ -71,7 +71,7 @@
Response::redirectTo('index.php');
exit();
}
- $code = isset($_POST['2fa_code']) ? $_POST['2fa_code'] : null;
+ $code = Request::post('2fa_code');
// verify entered code
$tfa = new FroxlorTwoFactorAuth('Froxlor ' . Settings::Get('system.hostname'));
// get user-data
@@ -162,8 +162,8 @@
exit();
} elseif ($action == 'login') {
if (!empty($_POST)) {
- $loginname = Validate::validate($_POST['loginname'], 'loginname');
- $password = Validate::validate($_POST['password'], 'password');
+ $loginname = Validate::validate(Request::post('loginname'), 'loginname');
+ $password = Validate::validate(Request::post('password'), 'password');
$select_additional = '';
if (Settings::Get('panel.db_version') >= 202312230) {
@@ -272,7 +272,7 @@
$rstlog = FroxlorLogger::getInstanceOf([
'loginname' => $_SERVER['REMOTE_ADDR']
]);
- $rstlog->logAction(FroxlorLogger::LOGIN_ACTION, LOG_WARNING, "Unknown user '" . $loginname . "' tried to login.");
+ $rstlog->logAction(FroxlorLogger::LOGIN_ACTION, LOG_WARNING, "Unknown user tried to login.");
Response::redirectTo('index.php', [
'showmessage' => '2'
@@ -334,7 +334,7 @@
$rstlog = FroxlorLogger::getInstanceOf([
'loginname' => $_SERVER['REMOTE_ADDR']
]);
- $rstlog->logAction(FroxlorLogger::LOGIN_ACTION, LOG_WARNING, "User '" . $loginname . "' tried to login with wrong password.");
+ $rstlog->logAction(FroxlorLogger::LOGIN_ACTION, LOG_WARNING, "User tried to login with wrong password.");
unset($userinfo);
Response::redirectTo('index.php', [
@@ -412,7 +412,7 @@
}
exit();
} else {
- $smessage = isset($_GET['showmessage']) ? (int)$_GET['showmessage'] : 0;
+ $smessage = (int)Request::get('showmessage', 0);
$message = '';
$successmessage = '';
@@ -449,25 +449,20 @@
}
// Pass the last used page if needed
- $lastscript = "";
- if (isset($_REQUEST['script']) && $_REQUEST['script'] != "") {
- $lastscript = $_REQUEST['script'];
+ $lastscript = Request::any('script', '');
+ if (!empty($lastscript)) {
$lastscript = str_replace("..", "", $lastscript);
$lastscript = htmlspecialchars($lastscript, ENT_QUOTES);
- if (!file_exists(__DIR__ . "/" . $lastscript)) {
+ if (file_exists(__DIR__ . "/" . $lastscript)) {
+ $_SESSION['lastscript'] = $lastscript;
+ } else {
$lastscript = "";
}
}
- $lastqrystr = "";
- if (isset($_REQUEST['qrystr']) && $_REQUEST['qrystr'] != "") {
- $lastqrystr = urlencode($_REQUEST['qrystr']);
- }
-
- if (!empty($lastscript)) {
- $_SESSION['lastscript'] = $lastscript;
- }
+ $lastqrystr = Request::any('qrystr', '');
if (!empty($lastqrystr)) {
+ $lastqrystr = urlencode($lastqrystr);
$_SESSION['lastqrystr'] = $lastqrystr;
}
@@ -485,8 +480,8 @@
$message = '';
if (!empty($_POST)) {
- $loginname = Validate::validate($_POST['loginname'], 'loginname');
- $email = Validate::validateEmail($_POST['loginemail']);
+ $loginname = Validate::validate(Request::post('loginname'), 'loginname');
+ $email = Validate::validateEmail(Request::post('loginemail'));
$result_stmt = Database::prepare("SELECT `adminid`, `customerid`, `customernumber`, `firstname`, `name`, `company`, `email`, `loginname`, `def_language`, `deactivated` FROM `" . TABLE_PANEL_CUSTOMERS . "`
WHERE `loginname`= :loginname
AND `email`= :email");
@@ -653,7 +648,7 @@
$rstlog = FroxlorLogger::getInstanceOf([
'loginname' => 'password_reset'
]);
- $rstlog->logAction(FroxlorLogger::USR_ACTION, LOG_WARNING, "User '" . $loginname . "' requested to set a new password, but was not found in database!");
+ $rstlog->logAction(FroxlorLogger::USR_ACTION, LOG_WARNING, "Unknown user requested to set a new password, but was not found in database!");
$message = lng('login.usernotfound');
}
@@ -683,9 +678,9 @@
"oldest" => time() - 86400
]);
- if (isset($_GET['resetcode']) && strlen($_GET['resetcode']) == 50) {
+ $activationcode = Request::get('resetcode');
+ if (!empty($activationcode) && strlen($activationcode) == 50) {
// Check if activation code is valid
- $activationcode = $_GET['resetcode'];
$timestamp = substr($activationcode, 15, 10);
$third = substr($activationcode, 25, 15);
$check = substr($activationcode, 40, 10);
@@ -700,8 +695,8 @@
if ($result !== false) {
try {
- $new_password = Crypt::validatePassword($_POST['new_password'], true);
- $new_password_confirm = Crypt::validatePassword($_POST['new_password_confirm'], true);
+ $new_password = Crypt::validatePassword(Request::post('new_password'), true);
+ $new_password_confirm = Crypt::validatePassword(Request::post('new_password_confirm'), true);
} catch (Exception $e) {
$message = $e->getMessage();
}
diff --git a/install/updates/froxlor/update_2.1.inc.php b/install/updates/froxlor/update_2.1.inc.php
index 7c65b587d7..b7b55d5831 100644
--- a/install/updates/froxlor/update_2.1.inc.php
+++ b/install/updates/froxlor/update_2.1.inc.php
@@ -237,3 +237,18 @@
Update::showUpdateStep("Updating from 2.1.5 to 2.1.6", false);
Froxlor::updateToVersion('2.1.6');
}
+
+if (Froxlor::isFroxlorVersion('2.1.6')) {
+ Update::showUpdateStep("Updating from 2.1.6 to 2.1.7", false);
+ Froxlor::updateToVersion('2.1.7');
+}
+
+if (Froxlor::isFroxlorVersion('2.1.7')) {
+ Update::showUpdateStep("Updating from 2.1.7 to 2.1.8", false);
+ Froxlor::updateToVersion('2.1.8');
+}
+
+if (Froxlor::isFroxlorVersion('2.1.8')) {
+ Update::showUpdateStep("Updating from 2.1.8 to 2.1.9", false);
+ Froxlor::updateToVersion('2.1.9');
+}
diff --git a/install/updates/froxlor/update_2.2.inc.php b/install/updates/froxlor/update_2.2.inc.php
index d4ebe59121..2d6b2b765d 100644
--- a/install/updates/froxlor/update_2.2.inc.php
+++ b/install/updates/froxlor/update_2.2.inc.php
@@ -35,7 +35,7 @@
}
}
-if (Froxlor::isFroxlorVersion('2.1.6')) {
+if (Froxlor::isFroxlorVersion('2.1.9')) {
Update::showUpdateStep("Enhancing virtual email table");
Database::query("ALTER TABLE `" . TABLE_MAIL_VIRTUAL . "` ADD `spam_tag_level` float(4,1) NOT NULL DEFAULT 7.0;");
Database::query("ALTER TABLE `" . TABLE_MAIL_VIRTUAL . "` ADD `spam_kill_level` float(4,1) NOT NULL DEFAULT 14.0;");
@@ -55,6 +55,10 @@
Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'dkim' AND `varname` = 'dkim_domains';");
Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'dkim' AND `varname` = 'dkim_algorithm';");
Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'dkim' AND `varname` = 'dkim_notes';");
+ Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'dkim' AND `varname` = 'dkim_add_adsp';");
+ Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'dkim' AND `varname` = 'dkim_dkimkeys';");
+ Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'dkim' AND `varname` = 'dkim_servicetype';");
+ Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'dkim' AND `varname` = 'dkim_add_adsppolicy';");
Update::lastStepStatus(0);
if ($antispam_activated) {
diff --git a/lib/Froxlor/Ajax/Ajax.php b/lib/Froxlor/Ajax/Ajax.php
index fc14738934..1a1ae2e5d0 100644
--- a/lib/Froxlor/Ajax/Ajax.php
+++ b/lib/Froxlor/Ajax/Ajax.php
@@ -193,7 +193,8 @@ private function getUpdateCheck()
UI::initTwig();
try {
- $json_result = \Froxlor\Api\Commands\Froxlor::getLocal($this->userinfo)->checkUpdate();
+ $force = Request::get('force', 0);
+ $json_result = \Froxlor\Api\Commands\Froxlor::getLocal($this->userinfo, ['force' => $force])->checkUpdate();
$result = json_decode($json_result, true)['data'];
$result['full_version'] = Froxlor::getFullVersion();
$result['dbversion'] = Froxlor::DBVERSION;
diff --git a/lib/Froxlor/Api/Commands/DomainZones.php b/lib/Froxlor/Api/Commands/DomainZones.php
index eebe6b8d06..4a3020a1e2 100644
--- a/lib/Froxlor/Api/Commands/DomainZones.php
+++ b/lib/Froxlor/Api/Commands/DomainZones.php
@@ -115,7 +115,7 @@ public function add()
// validation
$errors = [];
- if (empty($record)) {
+ if (empty(trim($record))) {
$record = "@";
}
diff --git a/lib/Froxlor/Api/Commands/Domains.php b/lib/Froxlor/Api/Commands/Domains.php
index ad0d4c5542..52e204e797 100644
--- a/lib/Froxlor/Api/Commands/Domains.php
+++ b/lib/Froxlor/Api/Commands/Domains.php
@@ -2098,6 +2098,8 @@ public function update()
* @param bool $is_stdsubdomain
* optional, default false, specify whether it's a std-subdomain you are deleting as it does not count
* as subdomain-resource
+ * @param bool $delete_userfiles
+ * optional, delete email account files on filesystem (if any), default false
*
* @access admin
* @return string json-encoded array
@@ -2109,7 +2111,8 @@ public function delete()
$id = $this->getParam('id', true, 0);
$dn_optional = $id > 0;
$domainname = $this->getParam('domainname', $dn_optional, '');
- $is_stdsubdomain = $this->getParam('is_stdsubdomain', true, 0);
+ $is_stdsubdomain = $this->getBoolParam('is_stdsubdomain', true, 0);
+ $delete_user_emailfiles = $this->getBoolParam('delete_userfiles', true, 0);
$result = $this->apiCall('Domains.get', [
'id' => $id,
@@ -2133,6 +2136,14 @@ public function delete()
$idString = implode(' OR ', $idString);
if ($idString != '') {
+ if ($delete_user_emailfiles) {
+ // determine all connected email-accounts
+ $emailaccount_sel = Database::prepare("SELECT `email`, `homedir`, `maildir` FROM `" . TABLE_MAIL_USERS . "` WHERE " . $idString);
+ Database::pexecute($emailaccount_sel, $paramString, true, true);
+ while ($emailacc_row = $emailaccount_sel->fetch(PDO::FETCH_ASSOC)) {
+ Cronjob::inserttask(TaskId::DELETE_EMAIL_DATA, $emailacc_row['email'], FileDir::makeCorrectDir($emailacc_row['homedir'] . '/' . $emailacc_row['maildir']));
+ }
+ }
$del_stmt = Database::prepare("
DELETE FROM `" . TABLE_MAIL_USERS . "` WHERE " . $idString);
Database::pexecute($del_stmt, $paramString, true, true);
diff --git a/lib/Froxlor/Api/Commands/EmailAccounts.php b/lib/Froxlor/Api/Commands/EmailAccounts.php
index b69da105ef..df7f73ca2a 100644
--- a/lib/Froxlor/Api/Commands/EmailAccounts.php
+++ b/lib/Froxlor/Api/Commands/EmailAccounts.php
@@ -523,7 +523,7 @@ public function delete()
$result = $this->apiCall('Emails.get', [
'id' => $id,
'emailaddr' => $emailaddr
- ]);
+ ], true);
$id = $result['id'];
if (empty($result['popaccountid']) || $result['popaccountid'] == 0) {
@@ -563,7 +563,7 @@ public function delete()
}
if ($delete_userfiles) {
- Cronjob::inserttask(TaskId::DELETE_EMAIL_DATA, $customer['loginname'], $result['email_full']);
+ Cronjob::inserttask(TaskId::DELETE_EMAIL_DATA, $customer['loginname'], FileDir::makeCorrectDir($result['homedir'] . '/' . $result['maildir']));
}
// decrease usage for customer
diff --git a/lib/Froxlor/Api/Commands/Emails.php b/lib/Froxlor/Api/Commands/Emails.php
index 4569852f13..60e81f5974 100644
--- a/lib/Froxlor/Api/Commands/Emails.php
+++ b/lib/Froxlor/Api/Commands/Emails.php
@@ -221,12 +221,12 @@ public function get()
$customer_ids = $this->getAllowedCustomerIds('email');
$params['idea'] = ($id <= 0 ? $emailaddr : $id);
- $result_stmt = Database::prepare("SELECT v.*, u.`quota`, u.`imap`, u.`pop3`, u.`postfix`, u.`mboxsize`
+ $result_stmt = Database::prepare("SELECT v.*, u.`quota`, u.`imap`, u.`pop3`, u.`postfix`, u.`mboxsize` " . ($this->isInternal() ? ", `u`.`homedir`, `u`.`maildir`" : "") . "
FROM `" . TABLE_MAIL_VIRTUAL . "` v
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON v.`popaccountid` = u.`id`
WHERE v.`customerid` IN (" . implode(", ", $customer_ids) . ")
- AND " . (is_numeric($params['idea']) ? "v.`id`= :idea" : "(v.`email` = :idea OR v.`email_full` = :idea)")
- );
+ AND " . (is_numeric($params['idea']) ? "v.`id`= :idea" : "(v.`email` = :idea OR v.`email_full` = :idea)"
+ ));
$result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) {
$this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_INFO, "[API] get email address '" . $result['email_full'] . "'");
diff --git a/lib/Froxlor/Api/Commands/PhpSettings.php b/lib/Froxlor/Api/Commands/PhpSettings.php
index 588c04a63b..8c50066080 100644
--- a/lib/Froxlor/Api/Commands/PhpSettings.php
+++ b/lib/Froxlor/Api/Commands/PhpSettings.php
@@ -222,8 +222,8 @@ public function listingCount()
* optional request terminate timeout if FPM is used, default is '60s'
* @param string $phpfpm_reqslowtimeout
* optional request slowlog timeout if FPM is used, default is '5s'
- * @param bool $phpfpm_pass_authorizationheader
- * optional whether to pass authorization header to webserver if FPM is used, default is 0 (false)
+ * @param bool $pass_authorizationheader
+ * optional whether to pass authorization header to webserver if FPM/FCGID is used, default is 0 (false)
* @param bool $override_fpmconfig
* optional whether to override fpm-daemon-config value for the following settings if FPM is used,
* default is 0 (false)
@@ -276,7 +276,7 @@ public function add()
$fpm_enableslowlog = $this->getBoolParam('phpfpm_enable_slowlog', true, 0);
$fpm_reqtermtimeout = $this->getParam('phpfpm_reqtermtimeout', true, "60s");
$fpm_reqslowtimeout = $this->getParam('phpfpm_reqslowtimeout', true, "5s");
- $fpm_pass_authorizationheader = $this->getBoolParam('phpfpm_pass_authorizationheader', true, 0);
+ $pass_authorizationheader = $this->getBoolParam('pass_authorizationheader', true, 0);
$override_fpmconfig = $this->getBoolParam('override_fpmconfig', true, 0);
$def_fpmconfig = $this->apiCall('FpmDaemons.get', [
@@ -312,7 +312,6 @@ public function add()
$fpm_enableslowlog = 0;
$fpm_reqtermtimeout = 0;
$fpm_reqslowtimeout = 0;
- $fpm_pass_authorizationheader = 0;
$override_fpmconfig = 0;
} elseif (Settings::Get('phpfpm.enabled') == 1) {
$fpm_reqtermtimeout = Validate::validate($fpm_reqtermtimeout, 'phpfpm_reqtermtimeout', '/^([0-9]+)(|s|m|h|d)$/', '', [], true);
@@ -377,7 +376,7 @@ public function add()
'fpmreqslow' => $fpm_reqslowtimeout,
'phpsettings' => $phpsettings,
'fpmsettingid' => $fpm_config_id,
- 'fpmpassauth' => $fpm_pass_authorizationheader,
+ 'fpmpassauth' => $pass_authorizationheader,
'ofc' => $override_fpmconfig,
'pm' => $pmanager,
'max_children' => $max_children,
@@ -464,7 +463,7 @@ private function addForAllCustomers(bool $allow_all_customers, int $config_id)
* optional request terminate timeout if FPM is used, default is '60s'
* @param string $phpfpm_reqslowtimeout
* optional request slowlog timeout if FPM is used, default is '5s'
- * @param bool $phpfpm_pass_authorizationheader
+ * @param bool $pass_authorizationheader
* optional whether to pass authorization header to webserver if FPM is used, default is 0 (false)
* @param bool $override_fpmconfig
* optional whether to override fpm-daemon-config value for the following settings if FPM is used,
@@ -516,7 +515,7 @@ public function update()
$fpm_enableslowlog = $this->getBoolParam('phpfpm_enable_slowlog', true, $result['fpm_slowlog']);
$fpm_reqtermtimeout = $this->getParam('phpfpm_reqtermtimeout', true, $result['fpm_reqterm']);
$fpm_reqslowtimeout = $this->getParam('phpfpm_reqslowtimeout', true, $result['fpm_reqslow']);
- $fpm_pass_authorizationheader = $this->getBoolParam('phpfpm_pass_authorizationheader', true, $result['pass_authorizationheader']);
+ $pass_authorizationheader = $this->getBoolParam('pass_authorizationheader', true, $result['pass_authorizationheader']);
$override_fpmconfig = $this->getBoolParam('override_fpmconfig', true, $result['override_fpmconfig']);
$pmanager = $this->getParam('pm', true, $result['pm']);
$max_children = $this->getParam('max_children', true, $result['max_children']);
@@ -548,7 +547,6 @@ public function update()
$fpm_enableslowlog = 0;
$fpm_reqtermtimeout = 0;
$fpm_reqslowtimeout = 0;
- $fpm_pass_authorizationheader = 0;
$override_fpmconfig = 0;
} elseif (Settings::Get('phpfpm.enabled') == 1) {
$fpm_reqtermtimeout = Validate::validate($fpm_reqtermtimeout, 'phpfpm_reqtermtimeout', '/^([0-9]+)(|s|m|h|d)$/', '', [], true);
@@ -614,7 +612,7 @@ public function update()
'fpmreqslow' => $fpm_reqslowtimeout,
'phpsettings' => $phpsettings,
'fpmsettingid' => $fpm_config_id,
- 'fpmpassauth' => $fpm_pass_authorizationheader,
+ 'fpmpassauth' => $pass_authorizationheader,
'ofc' => $override_fpmconfig,
'pm' => $pmanager,
'max_children' => $max_children,
diff --git a/lib/Froxlor/Api/Commands/SysLog.php b/lib/Froxlor/Api/Commands/SysLog.php
index 9236d57772..2df7d1a133 100644
--- a/lib/Froxlor/Api/Commands/SysLog.php
+++ b/lib/Froxlor/Api/Commands/SysLog.php
@@ -90,6 +90,8 @@ public function listing()
}
Database::pexecute($result_stmt, $query_fields, true, true);
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
+ // clean log-text
+ $row['text'] = preg_replace("/[^\w @#\"':.()\[\]+\-_\/\\\!]/i", "_", $row['text']);
$result[] = $row;
}
$this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_INFO, "[API] list log-entries");
diff --git a/lib/Froxlor/Cli/UpdateCommand.php b/lib/Froxlor/Cli/UpdateCommand.php
index d7a255eb88..bca38420ef 100644
--- a/lib/Froxlor/Cli/UpdateCommand.php
+++ b/lib/Froxlor/Cli/UpdateCommand.php
@@ -58,6 +58,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
if ($input->getOption('database')) {
$result = $this->validateRequirements($output, true);
if ($result == self::SUCCESS) {
+ require Froxlor::getInstallDir() . '/lib/functions.php';
if (Froxlor::hasUpdates() || Froxlor::hasDbUpdates()) {
$output->writeln('' . lng('updates.dbupdate_required') . '>');
if ($input->getOption('check-only')) {
diff --git a/lib/Froxlor/Cron/Http/Apache.php b/lib/Froxlor/Cron/Http/Apache.php
index f4c6f6d1c7..609f916489 100644
--- a/lib/Froxlor/Cron/Http/Apache.php
+++ b/lib/Froxlor/Cron/Http/Apache.php
@@ -208,7 +208,9 @@ public function createIpPort()
];
$php = new PhpInterface($domain);
$phpconfig = $php->getPhpConfig(Settings::Get('system.mod_fcgid_defaultini_ownvhost'));
-
+ if ($phpconfig['pass_authorizationheader'] == '1') {
+ $this->virtualhosts_data[$vhosts_filename] .= ' FcgidPassHeader Authorization' . "\n";
+ }
$starter_filename = FileDir::makeCorrectFile($configdir . '/php-fcgi-starter');
$this->virtualhosts_data[$vhosts_filename] .= ' SuexecUserGroup "' . Settings::Get('system.mod_fcgid_httpuser') . '" "' . Settings::Get('system.mod_fcgid_httpgroup') . '"' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' ' . "\n";
@@ -279,7 +281,9 @@ public function createIpPort()
// start block, cut off last pipe and close block
$filesmatch = '(' . str_replace(".", "\.", substr($filesmatch, 0, -1)) . ')';
$this->virtualhosts_data[$vhosts_filename] .= ' ' . "\n";
- $this->virtualhosts_data[$vhosts_filename] .= ' SetHandler proxy:unix:' . $php->getInterface()->getSocketFile() . '|fcgi://localhost' . "\n";
+ $this->virtualhosts_data[$vhosts_filename] .= ' ' . "\n";
+ $this->virtualhosts_data[$vhosts_filename] .= ' SetHandler proxy:unix:' . $php->getInterface()->getSocketFile() . '|fcgi://localhost' . "\n";
+ $this->virtualhosts_data[$vhosts_filename] .= ' ' . "\n";
$this->virtualhosts_data[$vhosts_filename] .= ' ' . "\n";
if ($phpconfig['pass_authorizationheader'] == '1') {
$this->virtualhosts_data[$vhosts_filename] .= ' ' . "\n";
@@ -819,6 +823,7 @@ protected function getVhostContent($domain, $ssl_vhost = false)
$modrew_red = ' [R=' . $code . ';L,NE]';
}
+ $vhost_content .= $this->getLogfiles($domain);
// redirect everything, not only root-directory, #541
$vhost_content .= ' ' . "\n";
$vhost_content .= ' RewriteEngine On' . "\n";
diff --git a/lib/Froxlor/Cron/Http/Lighttpd.php b/lib/Froxlor/Cron/Http/Lighttpd.php
index 968ab62c08..92478a9424 100644
--- a/lib/Froxlor/Cron/Http/Lighttpd.php
+++ b/lib/Froxlor/Cron/Http/Lighttpd.php
@@ -406,6 +406,7 @@ protected function getVhostContent($domain, $ssl_vhost = false, $ipid = 0)
// Get domain's redirect code
$code = Domain::getDomainRedirectCode($domain['id']);
+ $vhost_content .= $this->getLogFiles($domain);
$vhost_content .= ' url.redirect-code = ' . $code . "\n";
$vhost_content .= ' url.redirect = (' . "\n";
$vhost_content .= ' "^/(.*)$" => "' . $uri . '$1"' . "\n";
diff --git a/lib/Froxlor/Cron/Http/Nginx.php b/lib/Froxlor/Cron/Http/Nginx.php
index 49246134cb..fe951784c7 100644
--- a/lib/Froxlor/Cron/Http/Nginx.php
+++ b/lib/Froxlor/Cron/Http/Nginx.php
@@ -604,6 +604,7 @@ protected function getVhostContent($domain, $ssl_vhost = false)
// Get domain's redirect code
$code = Domain::getDomainRedirectCode($domain['id']);
+ $vhost_content .= $this->getLogFiles($domain);
$vhost_content .= "\t" . 'location / {' . "\n";
$vhost_content .= "\t\t" . 'return ' . $code . ' ' . $uri . '$request_uri;' . "\n";
$vhost_content .= "\t" . '}' . "\n";
diff --git a/lib/Froxlor/Cron/System/ExportCron.php b/lib/Froxlor/Cron/System/ExportCron.php
index 8def5b7d32..b7cfd10be2 100644
--- a/lib/Froxlor/Cron/System/ExportCron.php
+++ b/lib/Froxlor/Cron/System/ExportCron.php
@@ -115,30 +115,46 @@ private static function createCustomerExport($data = null, $customerdocroot = nu
$has_dbs = false;
$current_dbserver = -1;
- while ($row = $sel_stmt->fetch()) {
- // Get sql_root data for the specific database-server the database resides on
- if ($current_dbserver != $row['dbserver']) {
- Database::needRoot(true, $row['dbserver']);
- Database::needSqlData();
- $sql_root = Database::getSqlData();
- Database::needRoot(false);
- // create temporary mysql-defaults file for the connection-credentials/details
- $mysqlcnf_file = tempnam("/tmp", "frx");
- $mysqlcnf = "[mysqldump]\npassword=" . $sql_root['passwd'] . "\nhost=" . $sql_root['host'] . "\n";
- if (!empty($sql_root['port'])) {
- $mysqlcnf .= "port=" . $sql_root['port'] . "\n";
- } elseif (!empty($sql_root['socket'])) {
- $mysqlcnf .= "socket=" . $sql_root['socket'] . "\n";
+
+ // look for mysqldump
+ $section = 'mysqldump';
+ if (file_exists("/usr/bin/mysqldump")) {
+ $mysql_dump = '/usr/bin/mysqldump';
+ } elseif (file_exists("/usr/local/bin/mysqldump")) {
+ $mysql_dump = '/usr/local/bin/mysqldump';
+ } elseif (file_exists("/usr/bin/mariadb-dump")) {
+ $mysql_dump = '/usr/bin/mariadb-dump';
+ $section = 'mariadb-dump';
+ }
+ if (!isset($mysql_dump)) {
+ $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, 'mysqldump/mariadb-dump executable could not be found. Please install mysql-client/mariadb-client package.');
+ } else {
+
+ while ($row = $sel_stmt->fetch()) {
+ // Get sql_root data for the specific database-server the database resides on
+ if ($current_dbserver != $row['dbserver']) {
+ Database::needRoot(true, $row['dbserver']);
+ Database::needSqlData();
+ $sql_root = Database::getSqlData();
+ Database::needRoot(false);
+ // create temporary mysql-defaults file for the connection-credentials/details
+ $mysqlcnf_file = tempnam("/tmp", "frx");
+ $mysqlcnf = "[".$section."]\npassword=" . $sql_root['passwd'] . "\nhost=" . $sql_root['host'] . "\n";
+ if (!empty($sql_root['port'])) {
+ $mysqlcnf .= "port=" . $sql_root['port'] . "\n";
+ } elseif (!empty($sql_root['socket'])) {
+ $mysqlcnf .= "socket=" . $sql_root['socket'] . "\n";
+ }
+ file_put_contents($mysqlcnf_file, $mysqlcnf);
}
- file_put_contents($mysqlcnf_file, $mysqlcnf);
+ $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> '.basename($mysql_dump) . ' -u ' . escapeshellarg($sql_root['user']) . ' -pXXXXX ' . $row['databasename'] . ' > ' . FileDir::makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'));
+ $bool_false = false;
+ FileDir::safe_exec($mysql_dump . ' --defaults-file=' . escapeshellarg($mysqlcnf_file) . ' -u ' . escapeshellarg($sql_root['user']) . ' ' . $row['databasename'] . ' > ' . FileDir::makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'), $bool_false, [
+ '>'
+ ]);
+ $has_dbs = true;
+ $current_dbserver = $row['dbserver'];
}
- $cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mysqldump -u ' . escapeshellarg($sql_root['user']) . ' -pXXXXX ' . $row['databasename'] . ' > ' . FileDir::makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'));
- $bool_false = false;
- FileDir::safe_exec('mysqldump --defaults-file=' . escapeshellarg($mysqlcnf_file) . ' -u ' . escapeshellarg($sql_root['user']) . ' ' . $row['databasename'] . ' > ' . FileDir::makeCorrectFile($tmpdir . '/mysql/' . $row['databasename'] . '_' . date('YmdHi', time()) . '.sql'), $bool_false, [
- '>'
- ]);
- $has_dbs = true;
- $current_dbserver = $row['dbserver'];
}
if ($has_dbs) {
diff --git a/lib/Froxlor/Cron/System/TasksCron.php b/lib/Froxlor/Cron/System/TasksCron.php
index 508f0cdc48..a10b2fd592 100644
--- a/lib/Froxlor/Cron/System/TasksCron.php
+++ b/lib/Froxlor/Cron/System/TasksCron.php
@@ -355,24 +355,16 @@ private static function deleteEmailData($row = null)
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'TasksCron: Task7 started - deleting customer e-mail data');
if (is_array($row['data'])) {
- if (isset($row['data']['loginname']) && isset($row['data']['email'])) {
+ if (isset($row['data']['loginname']) && isset($row['data']['emailpath'])) {
// remove specific maildir
- $email_full = $row['data']['email'];
+ $email_full = $row['data']['emailpath'];
if (empty($email_full)) {
- FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, 'FATAL: Task7 asks to delete a email account but email field is empty!');
- }
- $email_user = substr($email_full, 0, strrpos($email_full, "@"));
- $email_domain = substr($email_full, strrpos($email_full, "@") + 1);
- $maildirname = trim(Settings::Get('system.vmail_maildirname'));
- // Add trailing slash to Maildir if needed
- $maildirpath = $maildirname;
- if (!empty($maildirname) and substr($maildirname, -1) != "/") {
- $maildirpath .= "/";
+ FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, 'FATAL: Task7 asks to delete a email account but emailpath field is empty!');
}
- $maildir = FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/' . $email_domain . '/' . $email_user);
+ $maildir = FileDir::makeCorrectDir($email_full);
- if ($maildir != '/' && !empty($maildir) && !empty($email_full) && $maildir != Settings::Get('system.vmail_homedir') && substr($maildir, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir') && is_dir($maildir) && is_dir(FileDir::makeCorrectDir($maildir . '/' . $maildirpath)) && fileowner($maildir) == Settings::Get('system.vmail_uid') && filegroup($maildir) == Settings::Get('system.vmail_gid')) {
+ if ($maildir != '/' && !empty($maildir) && $maildir != Settings::Get('system.vmail_homedir') && substr($maildir, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir') && is_dir($maildir) && fileowner($maildir) == Settings::Get('system.vmail_uid') && filegroup($maildir) == Settings::Get('system.vmail_gid')) {
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir));
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
$return = false;
@@ -384,23 +376,6 @@ private static function deleteEmailData($row = null)
'~',
'?'
]);
- } else {
- // backward-compatibility for old folder-structure
- $maildir_old = FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/' . $row['data']['email']);
-
- if ($maildir_old != '/' && !empty($maildir_old) && $maildir_old != Settings::Get('system.vmail_homedir') && substr($maildir_old, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir') && is_dir($maildir_old) && fileowner($maildir_old) == Settings::Get('system.vmail_uid') && filegroup($maildir_old) == Settings::Get('system.vmail_gid')) {
- FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir_old));
- // mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
- $return = false;
- FileDir::safe_exec('rm -rf ' . escapeshellarg($maildir_old), $return, [
- '|',
- '&',
- '`',
- '$',
- '~',
- '?'
- ]);
- }
}
}
}
diff --git a/lib/Froxlor/Cron/Traffic/ReportsCron.php b/lib/Froxlor/Cron/Traffic/ReportsCron.php
index 01828c1d7c..cd8babafec 100644
--- a/lib/Froxlor/Cron/Traffic/ReportsCron.php
+++ b/lib/Froxlor/Cron/Traffic/ReportsCron.php
@@ -211,7 +211,7 @@ public static function run()
$_mailerror = false;
$mailerr_msg = "";
try {
- $mail->SetFrom($row['email'], $row['name']);
+ $mail->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
$mail->Subject = $mail_subject;
$mail->AltBody = $mail_body;
$mail->MsgHTML(nl2br($mail_body));
@@ -297,7 +297,7 @@ public static function run()
$_mailerror = false;
$mailerr_msg = "";
try {
- $mail->SetFrom($row['email'], $row['name']);
+ $mail->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
$mail->Subject = $mail_subject;
$mail->Body = $mail_body;
$mail->MsgHTML(nl2br($mail_body));
@@ -472,7 +472,7 @@ private static function usageDiskspace()
$_mailerror = false;
$mailerr_msg = "";
try {
- $mail->SetFrom($row['email'], $row['name']);
+ $mail->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));
$mail->Subject = $mail_subject;
$mail->AltBody = $mail_body;
$mail->MsgHTML(nl2br($mail_body));
diff --git a/lib/Froxlor/Database/DbManager.php b/lib/Froxlor/Database/DbManager.php
index eeb1e4431a..4d56906ca5 100644
--- a/lib/Froxlor/Database/DbManager.php
+++ b/lib/Froxlor/Database/DbManager.php
@@ -110,7 +110,7 @@ public static function correctMysqlUsers(array $mysql_access_host_array)
$users = $dbm->getManager()->getAllSqlUsers(false);
foreach ($databases[$dbserver['dbserver']] as $username) {
- if (isset($users[$username]) && is_array($users[$username]) && isset($users[$username]['hosts']) && is_array($users[$username]['hosts'])) {
+ if (isset($users[$username]['hosts']) && is_array($users[$username]['hosts'])) {
$password = [
'password' => $users[$username]['password'],
diff --git a/lib/Froxlor/Database/Manager/DbManagerMySQL.php b/lib/Froxlor/Database/Manager/DbManagerMySQL.php
index 77e59495ed..a73a1be402 100644
--- a/lib/Froxlor/Database/Manager/DbManagerMySQL.php
+++ b/lib/Froxlor/Database/Manager/DbManagerMySQL.php
@@ -82,7 +82,8 @@ public function createDatabase(string $dbname = null)
*/
public function grantPrivilegesTo(string $username, $password, string $access_host = null, bool $p_encrypted = false, bool $update = false, bool $grant_access_prefix = false)
{
- $pwd_plugin = 'mysql_native_password';
+ // this is required for mysql8
+ $pwd_plugin = 'caching_sha2_password';
if (is_array($password) && count($password) == 2) {
$pwd_plugin = $password['plugin'];
$password = $password['password'];
@@ -278,7 +279,7 @@ public function getAllSqlUsers(bool $user_only = true): array
if (!isset($allsqlusers[$row['User']]) || !is_array($allsqlusers[$row['User']])) {
$allsqlusers[$row['User']] = [
'password' => $row['Password'] ?? $row['authentication_string'],
- 'plugin' => $row['plugin'] ?? 'mysql_native_password',
+ 'plugin' => $row['plugin'] ?? 'caching_sha2_password',
'hosts' => []
];
}
diff --git a/lib/Froxlor/FileDir.php b/lib/Froxlor/FileDir.php
index acb8fb9a58..0b3b529adb 100644
--- a/lib/Froxlor/FileDir.php
+++ b/lib/Froxlor/FileDir.php
@@ -140,6 +140,12 @@ public static function makeCorrectDir(string $dir, string $fixed_homedir = ""):
if (is_link($check_dir)) {
$original_target = $check_dir;
$check_dir = readlink($check_dir);
+ $link_dir = dirname($original_target);
+ // check whether the link is relative or absolute
+ if (substr($check_dir, 0, 1) != '/') {
+ // relative directory, prepend link_dir
+ $check_dir = $link_dir . '/' . $check_dir;
+ }
if (substr($check_dir, 0, strlen($fixed_homedir)) != $fixed_homedir) {
throw new Exception("Found symlink pointing outside of customer home directory: " . substr($original_target, strlen($fixed_homedir)));
}
@@ -287,7 +293,7 @@ public static function getUnknownDomainTemplate(string $servername = "")
$tpl_content = lng('admin.templates.unconfigured_content_fallback');
}
}
- $redirect_file = FileDir::makeCorrectFile(Froxlor::getInstallDir().'/notice.'.$tpl_ext);
+ $redirect_file = FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/notice.' . $tpl_ext);
file_put_contents($redirect_file, $tpl_content);
return basename($redirect_file);
}
diff --git a/lib/Froxlor/Froxlor.php b/lib/Froxlor/Froxlor.php
index dcebc533a4..87ccc013e9 100644
--- a/lib/Froxlor/Froxlor.php
+++ b/lib/Froxlor/Froxlor.php
@@ -39,7 +39,7 @@ final class Froxlor
// Distribution branding-tag (used for Debian etc.)
const BRANDING = '';
- const DOCS_URL = 'https://docs.froxlor.org/v2.2/';
+ const DOCS_URL = 'https://docs.froxlor.org';
/**
* return path to where froxlor is installed, e.g.
@@ -52,6 +52,14 @@ public static function getInstallDir(): string
return dirname(__DIR__, 2) . '/';
}
+ public static function getDocsUrl(): string
+ {
+ if (preg_match('/(.+)-(dev|beta|rc)\d+$/', self::VERSION)) {
+ return self::DOCS_URL . '/dev/';
+ }
+ return self::DOCS_URL . '/v' . self::getShortVersion() . '/';
+ }
+
/**
* return basic version
*
@@ -62,6 +70,16 @@ public static function getVersion(): string
return self::VERSION;
}
+ /**
+ * return short basic version
+ *
+ * @return string
+ */
+ public static function getShortVersion(): string
+ {
+ return explode(".", self::VERSION)[0] . '.' . explode(".", self::VERSION)[1];
+ }
+
/**
* return version + branding and database-version
*
diff --git a/lib/Froxlor/FroxlorLogger.php b/lib/Froxlor/FroxlorLogger.php
index 2ca02aeb08..6eeadf7fdc 100644
--- a/lib/Froxlor/FroxlorLogger.php
+++ b/lib/Froxlor/FroxlorLogger.php
@@ -175,6 +175,9 @@ public function logAction($action = FroxlorLogger::USR_ACTION, int $type = LOG_N
$this->initMonolog();
}
+ // clean log-text
+ $text = preg_replace("/[^\w @#\"':.()\[\]+\-_\/\\\!]/i", "_", $text);
+
if (self::$crondebug_flag || ($action == FroxlorLogger::CRON_ACTION && $type <= LOG_WARNING)) {
echo "[" . $this->getLogLevelDesc($type) . "] " . $text . PHP_EOL;
}
diff --git a/lib/Froxlor/Install/Install/Core.php b/lib/Froxlor/Install/Install/Core.php
index f30e689108..22d45e2bf9 100644
--- a/lib/Froxlor/Install/Install/Core.php
+++ b/lib/Froxlor/Install/Install/Core.php
@@ -176,15 +176,19 @@ private function backupExistingDatabase(object &$db_root)
$filename = "/tmp/froxlor_backup_" . date('YmdHi') . ".sql";
// look for mysqldump
+ $section = 'mysqldump';
if (file_exists("/usr/bin/mysqldump")) {
$mysql_dump = '/usr/bin/mysqldump';
} elseif (file_exists("/usr/local/bin/mysqldump")) {
$mysql_dump = '/usr/local/bin/mysqldump';
+ } elseif (file_exists("/usr/bin/mariadb-dump")) {
+ $mysql_dump = '/usr/bin/mariadb-dump';
+ $section = 'mariadb-dump';
}
// create temporary .cnf file
$cnffilename = "/tmp/froxlor_dump.cnf";
- $dumpcnf = "[mysqldump]" . PHP_EOL . "password=\"" . $this->validatedData['mysql_root_pass'] . "\"" . PHP_EOL;
+ $dumpcnf = "[".$section."]" . PHP_EOL . "password=\"" . $this->validatedData['mysql_root_pass'] . "\"" . PHP_EOL;
file_put_contents($cnffilename, $dumpcnf);
// make the backup
@@ -195,7 +199,7 @@ private function backupExistingDatabase(object &$db_root)
@unlink($cnffilename);
if (stristr(implode(" ", $output), "error")) {
throw new Exception(lng('install.errors.mysqldump_backup_failed'));
- } else if (!file_exists($filename)) {
+ } elseif (!file_exists($filename)) {
throw new Exception(lng('install.errors.sql_backup_file_missing'));
}
} else {
@@ -379,7 +383,7 @@ private function doSettings(object &$db_user)
$this->updateSetting($upd_stmt, 1, 'system', 'leenabled');
$this->updateSetting($upd_stmt, 1, 'system', 'le_froxlor_enabled');
}
- $this->updateSetting($upd_stmt, $this->validatedData['servername'], 'system', 'hostname');
+ $this->updateSetting($upd_stmt, strtolower($this->validatedData['servername']), 'system', 'hostname');
$this->updateSetting($upd_stmt, 'en', 'panel', 'standardlanguage'); // TODO: set language
$this->updateSetting($upd_stmt, $this->validatedData['mysql_access_host'], 'system', 'mysql_access_host');
$this->updateSetting($upd_stmt, $this->validatedData['webserver'], 'system', 'webserver');
diff --git a/lib/Froxlor/PhpHelper.php b/lib/Froxlor/PhpHelper.php
index 9a7243e117..77c1899367 100644
--- a/lib/Froxlor/PhpHelper.php
+++ b/lib/Froxlor/PhpHelper.php
@@ -417,6 +417,9 @@ public static function cleanGlobal(array &$global, AntiXSS &$antiXss)
'admin_pass',
'admin_pass_confirm',
'panel_password_special_char',
+ 'old_password',
+ 'new_password',
+ 'new_password_confirm',
];
if (!empty($global)) {
$tmp = $global;
diff --git a/lib/Froxlor/Settings/Store.php b/lib/Froxlor/Settings/Store.php
index 9b82ca0a99..be5f2cb9c7 100644
--- a/lib/Froxlor/Settings/Store.php
+++ b/lib/Froxlor/Settings/Store.php
@@ -36,6 +36,7 @@
use Froxlor\Settings;
use Froxlor\System\Cronjob;
use Froxlor\System\IPTools;
+use Froxlor\UI\Request;
use Froxlor\Validate\Validate;
use PDO;
@@ -465,7 +466,7 @@ public static function storeSettingImage($fieldname, $fielddata)
}
// Delete file?
- if ($fielddata['value'] !== "" && array_key_exists($fieldname . '_delete', $_POST) && $_POST[$fieldname . '_delete']) {
+ if ($fielddata['value'] !== "" && array_key_exists($fieldname . '_delete', $_POST) && Request::post($fieldname . '_delete')) {
@unlink(Froxlor::getInstallDir() . '/' . explode('?', $fielddata['value'], 2)[0]);
$save_to = '';
}
diff --git a/lib/Froxlor/System/Cronjob.php b/lib/Froxlor/System/Cronjob.php
index ba14458de7..1d4dcf8dea 100644
--- a/lib/Froxlor/System/Cronjob.php
+++ b/lib/Froxlor/System/Cronjob.php
@@ -190,7 +190,7 @@ public static function inserttask(int $type, ...$params)
} elseif ($type == TaskId::DELETE_EMAIL_DATA && count($params) == 2 && $params[0] != '' && $params[1] != '') {
$data = [];
$data['loginname'] = $params[0];
- $data['email'] = $params[1];
+ $data['emailpath'] = $params[1];
$data = json_encode($data);
Database::pexecute($ins_stmt, [
'type' => TaskId::DELETE_EMAIL_DATA,
diff --git a/lib/Froxlor/UI/HTML.php b/lib/Froxlor/UI/HTML.php
index 181399b117..d0e878f96d 100644
--- a/lib/Froxlor/UI/HTML.php
+++ b/lib/Froxlor/UI/HTML.php
@@ -33,10 +33,9 @@ class HTML
/**
* Build Navigation Sidebar
*
- * @param
- * array navigation data
- * @param
- * array userinfo the userinfo of the user
+ * @param array $navigation data
+ * @param array $userinfo the userinfo of the user
+ *
* @return array the content of the navigation bar according to user-permissions
*/
public static function buildNavigation(array $navigation, array $userinfo)
@@ -44,12 +43,19 @@ public static function buildNavigation(array $navigation, array $userinfo)
$returnvalue = [];
// sanitize user-given input (url-manipulation)
- if (isset($_GET['page']) && is_array($_GET['page'])) {
- $_GET['page'] = (string)$_GET['page'][0];
+ $req_page = Request::get('page');
+ if (!empty($req_page) && is_array($req_page)) {
+ $req_page = (string)array_shift($req_page);
}
- if (isset($_GET['action']) && is_array($_GET['action'])) {
- $_GET['action'] = (string)$_GET['action'][0];
+ // need to preserve this
+ $_GET['page'] = $req_page;
+
+ $req_action = Request::get('action');
+ if (!empty($req_action) && is_array($req_action)) {
+ $req_action = (string)array_shift($req_action);
}
+ // need to preserve this
+ $_GET['action'] = $req_action;
foreach ($navigation as $box) {
if ((!isset($box['show_element']) || $box['show_element'] === true) && (!isset($box['required_resources']) || $box['required_resources'] == '' || (isset($userinfo[$box['required_resources']]) && ((int)$userinfo[$box['required_resources']] > 0 || $userinfo[$box['required_resources']] == '-1')))) {
@@ -69,7 +75,7 @@ public static function buildNavigation(array $navigation, array $userinfo)
}
if (
- ((empty($_GET['page']) && substr_count($element['url'], "page=") == 0) || (isset($_GET['page']) && substr_count($element['url'], "page=" . $_GET['page']) > 0))
+ ((empty($req_page) && substr_count($element['url'], "page=") == 0) || (!empty($req_page) && substr_count($element['url'], "page=" . $req_page) > 0))
&& substr_count($element['url'], basename($_SERVER["SCRIPT_FILENAME"])) > 0
) {
$active = true;
diff --git a/lib/Froxlor/UI/Pagination.php b/lib/Froxlor/UI/Pagination.php
index e2f090ca0d..c746527c9f 100644
--- a/lib/Froxlor/UI/Pagination.php
+++ b/lib/Froxlor/UI/Pagination.php
@@ -61,11 +61,12 @@ class Pagination
*/
public function __construct(
array $fields = [],
- int $total_entries = 0,
- int $perPage = 20,
+ int $total_entries = 0,
+ int $perPage = 20,
array $default_sorting = [],
array $pagination_additional_params = []
- ) {
+ )
+ {
$this->fields = $fields;
$this->entries = $total_entries;
$this->perPage = $perPage;
@@ -80,12 +81,13 @@ public function __construct(
$orderfields = array_keys($fields);
$this->searchfield = $orderfields[0];
}
- if (isset($_REQUEST['searchtext']) && (preg_match('/[-_@\p{L}\p{N}*.]+$/u',
- $_REQUEST['searchtext']) || $_REQUEST['searchtext'] === '')) {
- $this->searchtext = trim($_REQUEST['searchtext']);
+ $searchtext = Request::any('searchtext');
+ if (isset($searchtext) && (preg_match('/[-_@\p{L}\p{N}*.]+$/u', $searchtext) || $searchtext === '')) {
+ $this->searchtext = trim($searchtext);
}
- if (isset($_REQUEST['searchfield']) && isset($fields[$_REQUEST['searchfield']])) {
- $this->searchfield = $_REQUEST['searchfield'];
+ $searchfield = Request::any('searchfield');
+ if (isset($searchfield) && isset($fields[$searchfield])) {
+ $this->searchfield = $searchfield;
}
if (!empty($this->searchtext) && !empty($this->searchfield)) {
$this->addSearch($this->searchtext, $this->searchfield);
@@ -94,11 +96,13 @@ public function __construct(
}
// check other ordering requests
- if (isset($_REQUEST['sortorder']) && (strtolower($_REQUEST['sortorder']) == 'desc' || strtolower($_REQUEST['sortorder']) == 'asc')) {
- $this->sortorder = strtoupper($_REQUEST['sortorder']);
+ $sortorder = Request::any('sortorder');
+ if (!empty($sortorder) && (strtolower($sortorder) == 'desc' || strtolower($sortorder) == 'asc')) {
+ $this->sortorder = strtoupper($sortorder);
}
- if (isset($_REQUEST['sortfield']) && isset($fields[$_REQUEST['sortfield']])) {
- $this->sortfield = $_REQUEST['sortfield'];
+ $sortfield = Request::any('sortfield');
+ if (!empty($sortfield) && isset($fields[$sortfield])) {
+ $this->sortfield = $sortfield;
$this->addOrderBy($this->sortfield, $this->sortorder);
} else {
// add default ordering by given order
@@ -118,8 +122,9 @@ public function __construct(
}
// check current page / pages
- if (isset($_REQUEST['pageno']) && intval($_REQUEST['pageno']) != 0) {
- $this->pageno = intval($_REQUEST['pageno']);
+ $pageno = Request::any('pageno');
+ if (!empty($pageno) && intval($pageno) != 0) {
+ $this->pageno = intval($pageno);
}
if (($this->pageno - 1) * Settings::Get('panel.paging') > $this->entries) {
$this->pageno = 1;
diff --git a/lib/Froxlor/UI/Request.php b/lib/Froxlor/UI/Request.php
index e053e8b14b..4e5016548f 100644
--- a/lib/Froxlor/UI/Request.php
+++ b/lib/Froxlor/UI/Request.php
@@ -30,14 +30,16 @@
class Request
{
+ private static $cleaned = false;
+
/**
* Get key from current $_GET or $_POST request.
*
* @param $key
- * @param string|null $default
+ * @param mixed|null $default
* @return mixed|string|null
*/
- public static function any($key, string $default = null)
+ public static function any($key, $default = null)
{
self::cleanAll();
@@ -48,10 +50,10 @@ public static function any($key, string $default = null)
* Get key from current $_GET request.
*
* @param $key
- * @param string|null $default
+ * @param mixed|null $default
* @return mixed|string|null
*/
- public static function get($key, string $default = null)
+ public static function get($key, $default = null)
{
self::cleanAll();
@@ -62,37 +64,56 @@ public static function get($key, string $default = null)
* Get key from current $_POST request.
*
* @param $key
- * @param string|null $default
+ * @param mixed|null $default
* @return mixed|string|null
*/
- public static function post($key, string $default = null)
+ public static function post($key, $default = null)
{
self::cleanAll();
return $_POST[$key] ?? $default;
}
+ /**
+ * return complete $_POST array
+ *
+ * @return array
+ */
+ public static function postAll()
+ {
+ self::cleanAll();
+
+ return $_POST ?? [];
+ }
+
/**
* Check for xss attempts and clean important globals and
* unsetting every variable registered in $_REQUEST and as variable itself
*/
public static function cleanAll()
{
- foreach ($_REQUEST as $key => $value) {
- if (isset($$key)) {
- unset($$key);
+ if (!self::$cleaned) {
+ foreach ($_REQUEST as $key => $value) {
+ if (isset($$key)) {
+ unset($$key);
+ }
}
- }
- unset($value);
+ unset($value);
+
+ $antiXss = new AntiXSS();
+ $antiXss->addNeverAllowedRegex([
+ '{{(.*)}}' => ''
+ ]);
- $antiXss = new AntiXSS();
+ // check $_GET
+ PhpHelper::cleanGlobal($_GET, $antiXss);
+ // check $_POST
+ PhpHelper::cleanGlobal($_POST, $antiXss);
+ // check $_COOKIE
+ PhpHelper::cleanGlobal($_COOKIE, $antiXss);
- // check $_GET
- PhpHelper::cleanGlobal($_GET, $antiXss);
- // check $_POST
- PhpHelper::cleanGlobal($_POST, $antiXss);
- // check $_COOKIE
- PhpHelper::cleanGlobal($_COOKIE, $antiXss);
+ self::$cleaned = true;
+ }
}
/**
diff --git a/lib/Froxlor/Validate/Check.php b/lib/Froxlor/Validate/Check.php
index 2d5229b15e..70c3c9f509 100644
--- a/lib/Froxlor/Validate/Check.php
+++ b/lib/Froxlor/Validate/Check.php
@@ -28,6 +28,7 @@
use Froxlor\Database\Database;
use Froxlor\FileDir;
use Froxlor\Settings;
+use Froxlor\UI\Request;
class Check
{
@@ -73,7 +74,7 @@ public static function checkFcgidPhpFpm($fieldname, $fielddata, $newfieldvalue,
// interface is to be enabled
if ((int)$newfieldvalue == 1) {
// check for POST value of the other field == 1 (active)
- if (isset($_POST[$check_array[$fieldname]['other_post_field']]) && (int)$_POST[$check_array[$fieldname]['other_post_field']] == 1) {
+ if ((int)Request::post($check_array[$fieldname]['other_post_field'], 0) == 1) {
// the other interface is activated already and STAYS activated
if ((int)Settings::Get($check_array[$fieldname]['other_enabled']) == 1) {
$returnvalue = [
@@ -83,8 +84,12 @@ public static function checkFcgidPhpFpm($fieldname, $fielddata, $newfieldvalue,
} else {
// fcgid is being validated before fpm -> "ask" fpm about its state
if ($fieldname == 'system_mod_fcgid_enabled') {
- $returnvalue = self::checkFcgidPhpFpm('system_phpfpm_enabled', null,
- $check_array[$fieldname]['other_post_field'], null);
+ $returnvalue = self::checkFcgidPhpFpm(
+ 'system_phpfpm_enabled',
+ null,
+ $check_array[$fieldname]['other_post_field'],
+ null
+ );
} else {
// not, bot are nogo
$returnvalue = $returnvalue = [
@@ -117,8 +122,16 @@ public static function checkMysqlAccessHost($fieldname, $fielddata, $newfieldval
$mysql_access_host_array = array_unique(array_map('trim', explode(',', $newfieldvalue)));
foreach ($mysql_access_host_array as $host_entry) {
- if (Validate::validate_ip2($host_entry, true, 'invalidip', true, true, true, true,
- false) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
+ if (Validate::validate_ip2(
+ $host_entry,
+ true,
+ 'invalidip',
+ true,
+ true,
+ true,
+ true,
+ false
+ ) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
return [
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
'invalidmysqlhost',
@@ -204,8 +217,11 @@ public static function checkPathConflicts($fieldname, $fielddata, $newfieldvalue
}
// neither dir can be within the other nor can they be equal
- if (substr($newdir, 0, strlen($cdir)) == $cdir || substr($cdir, 0,
- strlen($newdir)) == $newdir || $newdir == $cdir) {
+ if (substr($newdir, 0, strlen($cdir)) == $cdir || substr(
+ $cdir,
+ 0,
+ strlen($newdir)
+ ) == $newdir || $newdir == $cdir) {
$returnvalue = [
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
'fcgidpathcannotbeincustomerdoc'
@@ -264,8 +280,11 @@ public static function checkUsername($fieldname, $fielddata, $newfieldvalue, $al
}
$returnvalue = [];
- if (Validate::validateUsername($newfieldvalue, Settings::Get('panel.unix_names'),
- Database::getSqlUsernameLength() - strlen($allnewfieldvalues['customer_mysqlprefix'])) === true) {
+ if (Validate::validateUsername(
+ $newfieldvalue,
+ Settings::Get('panel.unix_names'),
+ Database::getSqlUsernameLength() - strlen($allnewfieldvalues['customer_mysqlprefix'])
+ ) === true) {
$returnvalue = [
self::FORMFIELDS_PLAUSIBILITY_CHECK_OK
];
@@ -330,7 +349,7 @@ public static function checkPgpPublicKeySetting($fieldname, $fielddata, $newfiel
];
}
// check if the pgp public key is a valid key
- putenv('GNUPGHOME='.sys_get_temp_dir());
+ putenv('GNUPGHOME=' . sys_get_temp_dir());
if (gnupg_import(gnupg_init(), $newfieldvalue) === false) {
return [
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
diff --git a/lib/configfiles/bookworm.xml b/lib/configfiles/bookworm.xml
index 72e5ab62a6..e00236bd0e 100644
--- a/lib/configfiles/bookworm.xml
+++ b/lib/configfiles/bookworm.xml
@@ -168,8 +168,9 @@ include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
- bin/froxlor-cli /usr/local/bin/froxlor-cli]]>
+ bin/froxlor-cli /usr/local/bin/froxlor-cli]]>
bin/froxlor-cli froxlor:cron --run-task 99]]>
diff --git a/lib/configfiles/bullseye.xml b/lib/configfiles/bullseye.xml
index 16cff61037..aaedc027da 100644
--- a/lib/configfiles/bullseye.xml
+++ b/lib/configfiles/bullseye.xml
@@ -168,8 +168,9 @@ include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
- bin/froxlor-cli /usr/local/bin/froxlor-cli]]>
+ bin/froxlor-cli /usr/local/bin/froxlor-cli]]>
bin/froxlor-cli froxlor:cron --run-task 99]]>
diff --git a/lib/configfiles/focal.xml b/lib/configfiles/focal.xml
index bd736cd603..dfda6e05da 100644
--- a/lib/configfiles/focal.xml
+++ b/lib/configfiles/focal.xml
@@ -167,8 +167,9 @@ include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
- bin/froxlor-cli /usr/local/bin/froxlor-cli]]>
+ bin/froxlor-cli /usr/local/bin/froxlor-cli]]>
bin/froxlor-cli froxlor:cron --run-task 99]]>
diff --git a/lib/configfiles/jammy.xml b/lib/configfiles/jammy.xml
index 1686c447b1..e1f5dab71f 100644
--- a/lib/configfiles/jammy.xml
+++ b/lib/configfiles/jammy.xml
@@ -167,8 +167,9 @@ include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
- bin/froxlor-cli /usr/local/bin/froxlor-cli]]>
+ bin/froxlor-cli /usr/local/bin/froxlor-cli]]>
bin/froxlor-cli froxlor:cron --run-task 99]]>
diff --git a/lib/configfiles/noble.xml b/lib/configfiles/noble.xml
new file mode 100644
index 0000000000..85039e4d54
--- /dev/null
+++ b/lib/configfiles/noble.xml
@@ -0,0 +1,4298 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{settings.system.apacheconf_vhost}}
+
+
+
+
+ {{settings.system.apacheconf_vhost}}
+
+
+
+
+
+
+ {{settings.system.apacheconf_diroptions}}
+
+
+
+
+ {{settings.system.apacheconf_diroptions}}
+
+
+
+
+
+
+
+
+ {{settings.system.deactivateddocroot}}
+
+
+
+
+
+
+
+
+ //service[@type='http']/general/commands
+
+
+
+ {{settings.system.use_ssl}}
+
+
+
+
+ {{settings.phpfpm.enabled}}
+
+
+
+
+ {{settings.system.leenabled}}
+
+
+ Require all granted
+
+]]>
+
+
+
+
+
+
+
+
+ "{{settings.system.letsencryptchallengepath}}/.well-known/acme-challenge/")
+
+# default listening port for IPv6 falls back to the IPv4 port
+include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
+include_shell "/usr/share/lighttpd/create-mime.assign.pl"
+include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
+]]>
+
+
+ //service[@type='http']/general/commands
+
+ {{settings.system.apacheconf_vhost}}
+
+ > /etc/lighttpd/lighttpd.conf]]>
+
+
+ {{settings.system.apacheconf_vhost}}
+
+ > /etc/lighttpd/lighttpd.conf]]>
+
+
+ {{settings.system.apacheconf_diroptions}}
+
+ > /etc/lighttpd/lighttpd.conf]]>
+
+
+ {{settings.system.apacheconf_diroptions}}
+
+ > /etc/lighttpd/lighttpd.conf]]>
+
+
+
+
+
+
+
+
+
+ {{settings.phpfpm.enabled}}
+
+ {{settings.system.mod_fcgid}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{settings.system.leenabled}}
+
+
+
+
+
+ {{settings.phpfpm.enabled}}
+
+ {{settings.system.mod_fcgid}}
+
+
+
+
+ //service[@type='http']/general/commands
+
+ {{settings.phpfpm.enabled}}
+
+ {{settings.system.mod_fcgid}}
+
+
+
+
+
+
+
+
+
+
+
+ > /etc/bind/named.conf.local]]>
+
+
+
+
+
+
+
+
+
+
+#################################
+# allow-dnsupdate-from A global setting to allow DNS updates from these IP ranges.
+#
+# allow-dnsupdate-from=127.0.0.0/8,::1
+
+#################################
+# allow-recursion List of subnets that are allowed to recurse
+#
+allow-recursion=127.0.0.1
+
+#################################
+# also-notify When notifying a domain, also notify these nameservers
+#
+# also-notify=
+
+#################################
+# any-to-tcp Answer ANY queries with tc=1, shunting to TCP
+#
+# any-to-tcp=no
+
+#################################
+# cache-ttl Seconds to store packets in the PacketCache
+#
+# cache-ttl=20
+
+#################################
+# carbon-interval Number of seconds between carbon (graphite) updates
+#
+# carbon-interval=30
+
+#################################
+# carbon-ourname If set, overrides our reported hostname for carbon stats
+#
+# carbon-ourname=
+
+#################################
+# carbon-server If set, send metrics in carbon (graphite) format to this server
+#
+# carbon-server=
+
+#################################
+# chroot If set, chroot to this directory for more security
+#
+# chroot=
+
+#################################
+# config-dir Location of configuration directory (pdns.conf)
+#
+config-dir=/etc/powerdns
+
+#################################
+# config-name Name of this virtual configuration - will rename the binary image
+#
+# config-name=
+
+#################################
+# control-console Debugging switch - don't use
+#
+# control-console=no
+
+#################################
+# daemon Operate as a daemon
+#
+daemon=yes
+
+#################################
+# default-ksk-algorithms Default KSK algorithms
+#
+# default-ksk-algorithms=rsasha256
+
+#################################
+# default-ksk-size Default KSK size (0 means default)
+#
+# default-ksk-size=0
+
+#################################
+# default-soa-mail mail address to insert in the SOA record if none set in the backend
+#
+# default-soa-mail=
+
+#################################
+# default-soa-name name to insert in the SOA record if none set in the backend
+#
+# default-soa-name=a.misconfigured.powerdns.server
+
+#################################
+# default-ttl Seconds a result is valid if not set otherwise
+#
+# default-ttl=3600
+
+#################################
+# default-zsk-algorithms Default ZSK algorithms
+#
+# default-zsk-algorithms=rsasha256
+
+#################################
+# default-zsk-size Default ZSK size (0 means default)
+#
+# default-zsk-size=0
+
+#################################
+# direct-dnskey Fetch DNSKEY RRs from backend during DNSKEY synthesis
+#
+# direct-dnskey=no
+
+#################################
+# disable-axfr Disable zonetransfers but do allow TCP queries
+#
+# disable-axfr=no
+
+#################################
+# disable-axfr-rectify Disable the rectify step during an outgoing AXFR. Only required for regression testing.
+#
+# disable-axfr-rectify=no
+
+#################################
+# disable-tcp Do not listen to TCP queries
+#
+# disable-tcp=no
+
+#################################
+# distributor-threads Default number of Distributor (backend) threads to start
+#
+# distributor-threads=3
+
+#################################
+# do-ipv6-additional-processing Do AAAA additional processing
+#
+# do-ipv6-additional-processing=yes
+
+#################################
+# edns-subnet-processing If we should act on EDNS Subnet options
+#
+# edns-subnet-processing=no
+
+#################################
+# entropy-source If set, read entropy from this file
+#
+# entropy-source=/dev/urandom
+
+#################################
+# experimental-api-key REST API Static authentication key (required for API use)
+#
+# experimental-api-key=
+
+#################################
+# experimental-api-readonly If the JSON API should disallow data modification
+#
+# experimental-api-readonly=no
+
+#################################
+# experimental-dname-processing If we should support DNAME records
+#
+# experimental-dname-processing=no
+
+#################################
+# experimental-dnsupdate Enable/Disable DNS update (RFC2136) support. Default is no.
+#
+# experimental-dnsupdate=no
+
+#################################
+# experimental-json-interface If the webserver should serve JSON data
+#
+# experimental-json-interface=no
+
+#################################
+# experimental-logfile Filename of the log file for JSON parser
+#
+# experimental-logfile=/var/log/pdns.log
+
+#################################
+# forward-dnsupdate A global setting to allow DNS update packages that are for a Slave domain, to be forwarded to the master.
+#
+# forward-dnsupdate=yes
+
+#################################
+# guardian Run within a guardian process
+#
+guardian=yes
+
+#################################
+# include-dir Include *.conf files from this directory
+#
+# include-dir=
+
+#################################
+# launch Which backends to launch and order to query them in
+#
+# launch=
+
+#################################
+# load-modules Load this module - supply absolute or relative path
+#
+# load-modules=
+
+#################################
+# local-address Local IP addresses to which we bind
+#
+local-address=,127.0.0.1
+
+#################################
+# local-address-nonexist-fail Fail to start if one or more of the local-address's do not exist on this server
+#
+# local-address-nonexist-fail=yes
+
+#################################
+# local-ipv6 Local IP address to which we bind
+#
+# local-ipv6=
+
+#################################
+# local-ipv6-nonexist-fail Fail to start if one or more of the local-ipv6 addresses do not exist on this server
+#
+# local-ipv6-nonexist-fail=yes
+
+#################################
+# local-port The port on which we listen
+#
+# local-port=53
+
+#################################
+# log-dns-details If PDNS should log DNS non-erroneous details
+#
+# log-dns-details=no
+
+#################################
+# log-dns-queries If PDNS should log all incoming DNS queries
+#
+# log-dns-queries=no
+
+#################################
+# logging-facility Log under a specific facility
+#
+# logging-facility=
+
+#################################
+# loglevel Amount of logging. Higher is more. Do not set below 3
+#
+# loglevel=4
+
+#################################
+# lua-prequery-script Lua script with prequery handler
+#
+# lua-prequery-script=
+
+#################################
+# master Act as a master
+#
+master=yes
+
+#################################
+# max-cache-entries Maximum number of cache entries
+#
+# max-cache-entries=1000000
+
+#################################
+# max-ent-entries Maximum number of empty non-terminals in a zone
+#
+# max-ent-entries=100000
+
+#################################
+# max-nsec3-iterations Limit the number of NSEC3 hash iterations
+#
+# max-nsec3-iterations=500
+
+#################################
+# max-queue-length Maximum queuelength before considering situation lost
+#
+# max-queue-length=5000
+
+#################################
+# max-signature-cache-entries Maximum number of signatures cache entries
+#
+# max-signature-cache-entries=
+
+#################################
+# max-tcp-connections Maximum number of TCP connections
+#
+# max-tcp-connections=10
+
+#################################
+# module-dir Default directory for modules
+#
+# module-dir=/usr/lib/TRIPLET/pdns
+
+#################################
+# negquery-cache-ttl Seconds to store negative query results in the QueryCache
+#
+# negquery-cache-ttl=60
+
+#################################
+# no-shuffle Set this to prevent random shuffling of answers - for regression testing
+#
+# no-shuffle=off
+
+#################################
+# only-notify Only send AXFR NOTIFY to these IP addresses or netmasks
+#
+# only-notify=0.0.0.0/0,::/0
+
+#################################
+# out-of-zone-additional-processing Do out of zone additional processing
+#
+# out-of-zone-additional-processing=yes
+
+#################################
+# overload-queue-length Maximum queuelength moving to packetcache only
+#
+# overload-queue-length=0
+
+#################################
+# pipebackend-abi-version Version of the pipe backend ABI
+#
+# pipebackend-abi-version=1
+
+#################################
+# prevent-self-notification Don't send notifications to what we think is ourself
+#
+# prevent-self-notification=yes
+
+#################################
+# query-cache-ttl Seconds to store query results in the QueryCache
+#
+# query-cache-ttl=20
+
+#################################
+# query-local-address Source IP address for sending queries
+#
+# query-local-address=0.0.0.0
+
+#################################
+# query-local-address6 Source IPv6 address for sending queries
+#
+# query-local-address6=::
+
+#################################
+# query-logging Hint backends that queries should be logged
+#
+# query-logging=no
+
+#################################
+# queue-limit Maximum number of milliseconds to queue a query
+#
+# queue-limit=1500
+
+#################################
+# receiver-threads Default number of receiver threads to start
+#
+# receiver-threads=1
+
+#################################
+# recursive-cache-ttl Seconds to store packets for recursive queries in the PacketCache
+#
+# recursive-cache-ttl=10
+
+#################################
+# recursor If recursion is desired, IP address of a recursing nameserver
+#
+# recursor=no
+
+#################################
+# retrieval-threads Number of AXFR-retrieval threads for slave operation
+#
+# retrieval-threads=2
+
+#################################
+# reuseport Enable higher performance on compliant kernels by using SO_REUSEPORT allowing each receiver thread to open its own socket
+#
+# reuseport=no
+
+#################################
+# security-poll-suffix Domain name from which to query security update notifications
+#
+# security-poll-suffix=secpoll.powerdns.com.
+
+#################################
+# send-root-referral Send out old-fashioned root-referral instead of ServFail in case of no authority
+#
+# send-root-referral=no
+
+#################################
+# server-id Returned when queried for 'server.id' TXT or NSID, defaults to hostname - disabled or custom
+#
+# server-id=
+
+#################################
+# setgid If set, change group id to this gid for more security
+#
+setgid=pdns
+
+#################################
+# setuid If set, change user id to this uid for more security
+#
+setuid=pdns
+
+#################################
+# signing-threads Default number of signer threads to start
+#
+# signing-threads=3
+
+#################################
+# slave Act as a slave
+#
+# slave=no
+
+#################################
+# slave-cycle-interval Reschedule failed SOA serial checks once every .. seconds
+#
+# slave-cycle-interval=60
+
+#################################
+# slave-renotify If we should send out notifications for slaved updates
+#
+# slave-renotify=no
+
+#################################
+# soa-expire-default Default SOA expire
+#
+# soa-expire-default=604800
+
+#################################
+# soa-minimum-ttl Default SOA minimum ttl
+#
+# soa-minimum-ttl=3600
+
+#################################
+# soa-refresh-default Default SOA refresh
+#
+# soa-refresh-default=10800
+
+#################################
+# soa-retry-default Default SOA retry
+#
+# soa-retry-default=3600
+
+#################################
+# socket-dir Where the controlsocket will live
+#
+# socket-dir=/var/run
+
+#################################
+# tcp-control-address If set, PowerDNS can be controlled over TCP on this address
+#
+# tcp-control-address=
+
+#################################
+# tcp-control-port If set, PowerDNS can be controlled over TCP on this address
+#
+# tcp-control-port=53000
+
+#################################
+# tcp-control-range If set, remote control of PowerDNS is possible over these networks only
+#
+# tcp-control-range=127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fe80::/10
+
+#################################
+# tcp-control-secret If set, PowerDNS can be controlled over TCP after passing this secret
+#
+# tcp-control-secret=
+
+#################################
+# traceback-handler Enable the traceback handler (Linux only)
+#
+# traceback-handler=yes
+
+#################################
+# trusted-notification-proxy IP address of incoming notification proxy
+#
+# trusted-notification-proxy=
+
+#################################
+# udp-truncation-threshold Maximum UDP response size before we truncate
+#
+# udp-truncation-threshold=1680
+
+#################################
+# version-string PowerDNS version in packets - full, anonymous, powerdns or custom
+#
+
+version-string=powerdns
+#################################
+# webserver Start a webserver for monitoring
+#
+# webserver=no
+
+#################################
+# webserver-address IP Address of webserver to listen on
+#
+# webserver-address=127.0.0.1
+
+#################################
+# webserver-allow-from Webserver access is only allowed from these subnets
+#
+# webserver-allow-from=0.0.0.0/0,::/0
+
+#################################
+# webserver-password Password required for accessing the webserver
+#
+# webserver-password=
+
+#################################
+# webserver-port Port of webserver to listen on
+#
+# webserver-port=8081
+
+#################################
+# webserver-print-arguments If the webserver should print arguments
+#
+# webserver-print-arguments=no
+
+# include froxlor-bind-specific config
+include-dir=/etc/powerdns/froxlor/
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#################################
+# allow-dnsupdate-from A global setting to allow DNS updates from these IP ranges.
+#
+# allow-dnsupdate-from=127.0.0.0/8,::1
+
+#################################
+# allow-recursion List of subnets that are allowed to recurse
+#
+allow-recursion=127.0.0.1
+
+#################################
+# also-notify When notifying a domain, also notify these nameservers
+#
+# also-notify=
+
+#################################
+# any-to-tcp Answer ANY queries with tc=1, shunting to TCP
+#
+# any-to-tcp=no
+
+#################################
+# cache-ttl Seconds to store packets in the PacketCache
+#
+# cache-ttl=20
+
+#################################
+# carbon-interval Number of seconds between carbon (graphite) updates
+#
+# carbon-interval=30
+
+#################################
+# carbon-ourname If set, overrides our reported hostname for carbon stats
+#
+# carbon-ourname=
+
+#################################
+# carbon-server If set, send metrics in carbon (graphite) format to this server
+#
+# carbon-server=
+
+#################################
+# chroot If set, chroot to this directory for more security
+#
+# chroot=
+
+#################################
+# config-dir Location of configuration directory (pdns.conf)
+#
+config-dir=/etc/powerdns
+
+#################################
+# config-name Name of this virtual configuration - will rename the binary image
+#
+# config-name=
+
+#################################
+# control-console Debugging switch - don't use
+#
+# control-console=no
+
+#################################
+# daemon Operate as a daemon
+#
+daemon=yes
+
+#################################
+# default-ksk-algorithms Default KSK algorithms
+#
+# default-ksk-algorithms=rsasha256
+
+#################################
+# default-ksk-size Default KSK size (0 means default)
+#
+# default-ksk-size=0
+
+#################################
+# default-soa-mail mail address to insert in the SOA record if none set in the backend
+#
+# default-soa-mail=
+
+#################################
+# default-soa-name name to insert in the SOA record if none set in the backend
+#
+# default-soa-name=a.misconfigured.powerdns.server
+
+#################################
+# default-ttl Seconds a result is valid if not set otherwise
+#
+# default-ttl=3600
+
+#################################
+# default-zsk-algorithms Default ZSK algorithms
+#
+# default-zsk-algorithms=rsasha256
+
+#################################
+# default-zsk-size Default ZSK size (0 means default)
+#
+# default-zsk-size=0
+
+#################################
+# direct-dnskey Fetch DNSKEY RRs from backend during DNSKEY synthesis
+#
+# direct-dnskey=no
+
+#################################
+# disable-axfr Disable zonetransfers but do allow TCP queries
+#
+# disable-axfr=no
+
+#################################
+# disable-axfr-rectify Disable the rectify step during an outgoing AXFR. Only required for regression testing.
+#
+# disable-axfr-rectify=no
+
+#################################
+# disable-tcp Do not listen to TCP queries
+#
+# disable-tcp=no
+
+#################################
+# distributor-threads Default number of Distributor (backend) threads to start
+#
+# distributor-threads=3
+
+#################################
+# do-ipv6-additional-processing Do AAAA additional processing
+#
+# do-ipv6-additional-processing=yes
+
+#################################
+# edns-subnet-processing If we should act on EDNS Subnet options
+#
+# edns-subnet-processing=no
+
+#################################
+# entropy-source If set, read entropy from this file
+#
+# entropy-source=/dev/urandom
+
+#################################
+# experimental-api-key REST API Static authentication key (required for API use)
+#
+# experimental-api-key=
+
+#################################
+# experimental-api-readonly If the JSON API should disallow data modification
+#
+# experimental-api-readonly=no
+
+#################################
+# experimental-dname-processing If we should support DNAME records
+#
+# experimental-dname-processing=no
+
+#################################
+# experimental-dnsupdate Enable/Disable DNS update (RFC2136) support. Default is no.
+#
+# experimental-dnsupdate=no
+
+#################################
+# experimental-json-interface If the webserver should serve JSON data
+#
+# experimental-json-interface=no
+
+#################################
+# experimental-logfile Filename of the log file for JSON parser
+#
+# experimental-logfile=/var/log/pdns.log
+
+#################################
+# forward-dnsupdate A global setting to allow DNS update packages that are for a Slave domain, to be forwarded to the master.
+#
+# forward-dnsupdate=yes
+
+#################################
+# guardian Run within a guardian process
+#
+guardian=yes
+
+#################################
+# include-dir Include *.conf files from this directory
+#
+# include-dir=
+
+#################################
+# launch Which backends to launch and order to query them in
+#
+# launch=
+launch=bind
+
+#################################
+# load-modules Load this module - supply absolute or relative path
+#
+# load-modules=
+
+#################################
+# local-address Local IP addresses to which we bind
+#
+local-address=,127.0.0.1
+
+#################################
+# local-address-nonexist-fail Fail to start if one or more of the local-address's do not exist on this server
+#
+# local-address-nonexist-fail=yes
+
+#################################
+# local-ipv6 Local IP address to which we bind
+#
+# local-ipv6=
+
+#################################
+# local-ipv6-nonexist-fail Fail to start if one or more of the local-ipv6 addresses do not exist on this server
+#
+# local-ipv6-nonexist-fail=yes
+
+#################################
+# local-port The port on which we listen
+#
+# local-port=53
+
+#################################
+# log-dns-details If PDNS should log DNS non-erroneous details
+#
+# log-dns-details=no
+
+#################################
+# log-dns-queries If PDNS should log all incoming DNS queries
+#
+# log-dns-queries=no
+
+#################################
+# logging-facility Log under a specific facility
+#
+# logging-facility=
+
+#################################
+# loglevel Amount of logging. Higher is more. Do not set below 3
+#
+# loglevel=4
+
+#################################
+# lua-prequery-script Lua script with prequery handler
+#
+# lua-prequery-script=
+
+#################################
+# master Act as a master
+#
+master=yes
+
+#################################
+# max-cache-entries Maximum number of cache entries
+#
+# max-cache-entries=1000000
+
+#################################
+# max-ent-entries Maximum number of empty non-terminals in a zone
+#
+# max-ent-entries=100000
+
+#################################
+# max-nsec3-iterations Limit the number of NSEC3 hash iterations
+#
+# max-nsec3-iterations=500
+
+#################################
+# max-queue-length Maximum queuelength before considering situation lost
+#
+# max-queue-length=5000
+
+#################################
+# max-signature-cache-entries Maximum number of signatures cache entries
+#
+# max-signature-cache-entries=
+
+#################################
+# max-tcp-connections Maximum number of TCP connections
+#
+# max-tcp-connections=10
+
+#################################
+# module-dir Default directory for modules
+#
+# module-dir=/usr/lib/TRIPLET/pdns
+
+#################################
+# negquery-cache-ttl Seconds to store negative query results in the QueryCache
+#
+# negquery-cache-ttl=60
+
+#################################
+# no-shuffle Set this to prevent random shuffling of answers - for regression testing
+#
+# no-shuffle=off
+
+#################################
+# only-notify Only send AXFR NOTIFY to these IP addresses or netmasks
+#
+# only-notify=0.0.0.0/0,::/0
+
+#################################
+# out-of-zone-additional-processing Do out of zone additional processing
+#
+# out-of-zone-additional-processing=yes
+
+#################################
+# overload-queue-length Maximum queuelength moving to packetcache only
+#
+# overload-queue-length=0
+
+#################################
+# pipebackend-abi-version Version of the pipe backend ABI
+#
+# pipebackend-abi-version=1
+
+#################################
+# prevent-self-notification Don't send notifications to what we think is ourself
+#
+# prevent-self-notification=yes
+
+#################################
+# query-cache-ttl Seconds to store query results in the QueryCache
+#
+# query-cache-ttl=20
+
+#################################
+# query-local-address Source IP address for sending queries
+#
+# query-local-address=0.0.0.0
+
+#################################
+# query-local-address6 Source IPv6 address for sending queries
+#
+# query-local-address6=::
+
+#################################
+# query-logging Hint backends that queries should be logged
+#
+# query-logging=no
+
+#################################
+# queue-limit Maximum number of milliseconds to queue a query
+#
+# queue-limit=1500
+
+#################################
+# receiver-threads Default number of receiver threads to start
+#
+# receiver-threads=1
+
+#################################
+# recursive-cache-ttl Seconds to store packets for recursive queries in the PacketCache
+#
+# recursive-cache-ttl=10
+
+#################################
+# recursor If recursion is desired, IP address of a recursing nameserver
+#
+# recursor=no
+
+#################################
+# retrieval-threads Number of AXFR-retrieval threads for slave operation
+#
+# retrieval-threads=2
+
+#################################
+# reuseport Enable higher performance on compliant kernels by using SO_REUSEPORT allowing each receiver thread to open its own socket
+#
+# reuseport=no
+
+#################################
+# security-poll-suffix Domain name from which to query security update notifications
+#
+# security-poll-suffix=secpoll.powerdns.com.
+
+#################################
+# send-root-referral Send out old-fashioned root-referral instead of ServFail in case of no authority
+#
+# send-root-referral=no
+
+#################################
+# server-id Returned when queried for 'server.id' TXT or NSID, defaults to hostname - disabled or custom
+#
+# server-id=
+
+#################################
+# setgid If set, change group id to this gid for more security
+#
+setgid=pdns
+
+#################################
+# setuid If set, change user id to this uid for more security
+#
+setuid=pdns
+
+#################################
+# signing-threads Default number of signer threads to start
+#
+# signing-threads=3
+
+#################################
+# slave Act as a slave
+#
+# slave=no
+
+#################################
+# slave-cycle-interval Reschedule failed SOA serial checks once every .. seconds
+#
+# slave-cycle-interval=60
+
+#################################
+# slave-renotify If we should send out notifications for slaved updates
+#
+# slave-renotify=no
+
+#################################
+# soa-expire-default Default SOA expire
+#
+# soa-expire-default=604800
+
+#################################
+# soa-minimum-ttl Default SOA minimum ttl
+#
+# soa-minimum-ttl=3600
+
+#################################
+# soa-refresh-default Default SOA refresh
+#
+# soa-refresh-default=10800
+
+#################################
+# soa-retry-default Default SOA retry
+#
+# soa-retry-default=3600
+
+#################################
+# socket-dir Where the controlsocket will live
+#
+# socket-dir=/var/run
+
+#################################
+# tcp-control-address If set, PowerDNS can be controlled over TCP on this address
+#
+# tcp-control-address=
+
+#################################
+# tcp-control-port If set, PowerDNS can be controlled over TCP on this address
+#
+# tcp-control-port=53000
+
+#################################
+# tcp-control-range If set, remote control of PowerDNS is possible over these networks only
+#
+# tcp-control-range=127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fe80::/10
+
+#################################
+# tcp-control-secret If set, PowerDNS can be controlled over TCP after passing this secret
+#
+# tcp-control-secret=
+
+#################################
+# traceback-handler Enable the traceback handler (Linux only)
+#
+# traceback-handler=yes
+
+#################################
+# trusted-notification-proxy IP address of incoming notification proxy
+#
+# trusted-notification-proxy=
+
+#################################
+# udp-truncation-threshold Maximum UDP response size before we truncate
+#
+# udp-truncation-threshold=1680
+
+#################################
+# version-string PowerDNS version in packets - full, anonymous, powerdns or custom
+#
+
+version-string=powerdns
+#################################
+# webserver Start a webserver for monitoring
+#
+# webserver=no
+
+#################################
+# webserver-address IP Address of webserver to listen on
+#
+# webserver-address=127.0.0.1
+
+#################################
+# webserver-allow-from Webserver access is only allowed from these subnets
+#
+# webserver-allow-from=0.0.0.0/0,::/0
+
+#################################
+# webserver-password Password required for accessing the webserver
+#
+# webserver-password=
+
+#################################
+# webserver-port Port of webserver to listen on
+#
+# webserver-port=8081
+
+#################################
+# webserver-print-arguments If the webserver should print arguments
+#
+# webserver-print-arguments=no
+
+# include froxlor-bind-specific config
+include-dir=/etc/powerdns/froxlor/
+]]>
+
+
+
+
+ named.conf
+
+# How often to check for zone changes. See 'Operation' section.
+bind-check-interval=180
+
+# Uncomment to enable Huffman compression on zone data.
+# Currently saves around 20% of memory actually used, but slows down operation.
+# bind-enable-huffman
+]]>
+
+
+
+
+
+
+
+
+
+
+
+ {{settings.system.vmail_gid}}
+
+
+
+
+ {{settings.system.vmail_uid}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+password =
+dbname =
+hosts =
+query = SELECT destination FROM mail_virtual AS v, panel_customers AS c WHERE c.customerid = v.customerid AND c.deactivated = 0 AND v.email = '%s' AND trim(v.destination) <> ''
+]]>
+
+
+
+
+password =
+dbname =
+hosts =
+query = SELECT domain FROM panel_domains WHERE domain = '%s' AND isemaildomain = '1' AND deactivated = 0
+]]>
+
+
+
+
+password =
+dbname =
+expansion_limit = 1
+hosts =
+query = SELECT CONCAT(homedir,maildir) FROM mail_users WHERE email = '%s'
+]]>
+
+
+
+
+password =
+dbname =
+hosts =
+query = SELECT DISTINCT username FROM mail_users WHERE email in ((SELECT mail_virtual.email_full FROM mail_virtual WHERE mail_virtual.email = '%s' UNION SELECT mail_virtual.destination FROM mail_virtual WHERE mail_virtual.email = '%s'));
+]]>
+
+
+
+
+password =
+dbname =
+expansion_limit = 1
+hosts =
+query = SELECT uid FROM mail_users WHERE email = '%s'
+]]>
+
+
+
+
+password =
+dbname =
+expansion_limit = 1
+hosts =
+query = SELECT gid FROM mail_users WHERE email = '%s'
+]]>
+
+
+
+
+]]>
+
+
+
+
+
+
+
+
+
+
+ //service[@type='smtp']/general/commands[@index=1]
+
+ //service[@type='smtp']/general/installs[@index=1]
+
+ //service[@type='smtp']/general/commands[@index=2]
+
+
+
+
+mydestination = $myhostname, localhost.$mydomain, localhost
+#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
+#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,
+# mail.$mydomain, www.$mydomain, ftp.$mydomain
+
+# The default setting is 550 (reject mail) but it is safer to start
+# with 450 (try again later) until you are certain that your
+# local_recipient_maps settings are OK.
+#
+unknown_local_recipient_reject_code = 550
+
+# The mailbox_command parameter specifies the optional external
+# command to use instead of mailbox delivery. The command is run as
+# the recipient with proper HOME, SHELL and LOGNAME environment settings.
+# Exception: delivery for root is done as $default_user.
+#
+# Other environment variables of interest: USER (recipient username),
+# EXTENSION (address extension), DOMAIN (domain part of address),
+# and LOCAL (the address localpart).
+#
+# Unlike other Postfix configuration parameters, the mailbox_command
+# parameter is not subjected to $parameter substitutions. This is to
+# make it easier to specify shell syntax (see example below).
+#
+# Avoid shell meta characters because they will force Postfix to run
+# an expensive shell process. Procmail alone is expensive enough.
+#
+# IF YOU USE THIS TO DELIVER MAIL SYSTEM-WIDE, YOU MUST SET UP AN
+# ALIAS THAT FORWARDS MAIL FOR ROOT TO A REAL USER.
+#
+mailbox_command = /usr/lib/dovecot/deliver
+#mailbox_command = /usr/bin/procmail -a "$EXTENSION"
+
+# The debugger_command specifies the external command that is executed
+# when a Postfix daemon program is run with the -D option.
+#
+# Use "command .. & sleep 5" so that the debugger can attach before
+# the process marches on. If you use an X-based debugger, be sure to
+# set up your XAUTHORITY environment variable before starting Postfix.
+#
+debugger_command =
+ PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
+ ddd $daemon_directory/$process_name $process_id & sleep 5
+
+inet_protocols = ipv4
+
+smtpd_helo_required = yes
+smtpd_recipient_restrictions = permit_mynetworks,
+ permit_sasl_authenticated,
+ reject_unauth_destination,
+ reject_unauth_pipelining,
+ reject_non_fqdn_recipient
+smtpd_sender_restrictions = permit_mynetworks,
+ reject_sender_login_mismatch,
+ permit_sasl_authenticated,
+ reject_unknown_helo_hostname,
+ reject_unknown_recipient_domain,
+ reject_unknown_sender_domain
+smtpd_client_restrictions = permit_mynetworks,
+ permit_sasl_authenticated,
+ reject_unknown_client_hostname
+
+# Postfix 2.10 requires this option. Postfix < 2.10 ignores this.
+# The option is intentionally left empty.
+smtpd_relay_restrictions =
+
+# Maximum size of Message in bytes (50MB)
+message_size_limit = 52428800
+
+## SASL Auth Settings
+smtpd_sasl_auth_enable = yes
+smtpd_sasl_local_domain = $myhostname
+broken_sasl_auth_clients = yes
+## Dovecot Settings for deliver, SASL Auth and virtual transport
+smtpd_sasl_type = dovecot
+virtual_transport = dovecot
+dovecot_destination_recipient_limit = 1
+smtpd_sasl_path = private/auth
+
+# Virtual delivery settings
+virtual_mailbox_base = /
+virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailbox_maps.cf
+virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_mailbox_domains.cf
+virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_alias_maps.cf
+smtpd_sender_login_maps = proxy:mysql:/etc/postfix/mysql-virtual_sender_permissions.cf
+virtual_uid_maps = static:
+virtual_gid_maps = static:
+
+# Local delivery settings
+local_transport = local
+alias_maps = $alias_database
+
+# Default Mailbox size, is set to 0 which means unlimited!
+mailbox_size_limit = 0
+virtual_mailbox_limit = 0
+
+### TLS settings
+###
+## TLS for outgoing mails from the server to another server
+smtp_tls_security_level = may
+smtp_tls_note_starttls_offer = yes
+## TLS for incoming connections (clients or other mail servers)
+smtpd_tls_security_level = may
+smtpd_tls_cert_file =
+smtpd_tls_key_file =
+#smtpd_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
+smtpd_tls_loglevel = 1
+smtpd_tls_received_header = yes
+smtp_use_tls = yes
+smtpd_use_tls = yes
+smtpd_tls_session_cache_timeout = 3600s
+]]>
+
+
+ //service[@type='smtp']/general/files[@index=0]
+
+
+
+
+ //service[@type='smtp']/general/commands[@index=3]
+
+
+
+
+
+
+
+
+
+
+
+
+ to select which instance is used (an alternative
+# to -c ). The instance name is also added to Dovecot processes
+# in ps output.
+#instance_name = dovecot
+
+# Greeting message for clients.
+#login_greeting = Dovecot ready.
+
+# Space separated list of trusted network ranges. Connections from these
+# IPs are allowed to override their IP addresses and ports (for logging and
+# for authentication checks). disable_plaintext_auth is also ignored for
+# these networks. Typically you'd specify your IMAP proxy servers here.
+#login_trusted_networks =
+
+# Space separated list of login access check sockets (e.g. tcpwrap)
+#login_access_sockets =
+
+# With proxy_maybe=yes if proxy destination matches any of these IPs, don't do
+# proxying. This isn't necessary normally, but may be useful if the destination
+# IP is e.g. a load balancer's IP.
+#auth_proxy_self =
+
+# Show more verbose process titles (in ps). Currently shows user name and
+# IP address. Useful for seeing who are actually using the IMAP processes
+# (eg. shared mailboxes or if same uid is used for multiple accounts).
+#verbose_proctitle = no
+
+# Should all processes be killed when Dovecot master process shuts down.
+# Setting this to "no" means that Dovecot can be upgraded without
+# forcing existing client connections to close (although that could also be
+# a problem if the upgrade is e.g. because of a security fix).
+#shutdown_clients = yes
+
+# If non-zero, run mail commands via this many connections to doveadm server,
+# instead of running them directly in the same process.
+#doveadm_worker_count = 0
+# UNIX socket or host:port used for connecting to doveadm server
+#doveadm_socket_path = doveadm-server
+
+# Space separated list of environment variables that are preserved on Dovecot
+# startup and passed down to all of its child processes. You can also give
+# key=value pairs to always set specific settings.
+#import_environment = TZ
+
+##
+## Dictionary server settings
+##
+
+# Dictionary can be used to store key=value lists. This is used by several
+# plugins. The dictionary can be accessed either directly or though a
+# dictionary server. The following dict block maps dictionary names to URIs
+# when the server is used. These can then be referenced using URIs in format
+# "proxy::".
+
+dict {
+ #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
+ #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext
+}
+
+# Most of the actual configuration gets included below. The filenames are
+# first sorted by their ASCII value and parsed in that order. The 00-prefixes
+# in filenames are intended to make it easier to understand the ordering.
+!include conf.d/*.conf
+
+# A config file can also tried to be included without giving an error if
+# it's not found:
+!include_try local.conf
+]]>
+
+
+
+ dbname= user= password="
+
+# Default password scheme.
+#
+# List of supported schemes is in
+# http://wiki2.dovecot.org/Authentication/PasswordSchemes
+#
+#default_pass_scheme = CRYPT
+
+# passdb query to retrieve the password. It can return fields:
+# password - The user's password. This field must be returned.
+# user - user@domain from the database. Needed with case-insensitive lookups.
+# username and domain - An alternative way to represent the "user" field.
+#
+# The "user" field is often necessary with case-insensitive lookups to avoid
+# e.g. "name" and "nAme" logins creating two different mail directories. If
+# your user and domain names are in separate fields, you can return "username"
+# and "domain" fields instead of "user".
+#
+# The query can also return other fields which have a special meaning, see
+# http://wiki2.dovecot.org/PasswordDatabase/ExtraFields
+#
+# Commonly used available substitutions (see http://wiki2.dovecot.org/Variables
+# for full list):
+# %u = entire user@domain
+# %n = user part of user@domain
+# %d = domain part of user@domain
+#
+# Note that these can be used only as input to SQL query. If the query outputs
+# any of these substitutions, they're not touched. Otherwise it would be
+# difficult to have eg. usernames containing '%' characters.
+#
+# Example:
+# password_query = SELECT userid AS user, pw AS password \
+# FROM users WHERE userid = '%u' AND active = 'Y'
+#
+#password_query = \
+# SELECT username, domain, password \
+# FROM users WHERE username = '%n' AND domain = '%d'
+
+# userdb query to retrieve the user information. It can return fields:
+# uid - System UID (overrides mail_uid setting)
+# gid - System GID (overrides mail_gid setting)
+# home - Home directory
+# mail - Mail location (overrides mail_location setting)
+#
+# None of these are strictly required. If you use a single UID and GID, and
+# home or mail directory fits to a template string, you could use userdb static
+# instead. For a list of all fields that can be returned, see
+# http://wiki2.dovecot.org/UserDatabase/ExtraFields
+#
+# Examples:
+# user_query = SELECT home, uid, gid FROM users WHERE userid = '%u'
+# user_query = SELECT dir AS home, user AS uid, group AS gid FROM users where userid = '%u'
+# user_query = SELECT home, 501 AS uid, 501 AS gid FROM users WHERE userid = '%u'
+#
+#user_query = \
+# SELECT home, uid, gid \
+# FROM users WHERE username = '%n' AND domain = '%d'
+user_query = SELECT CONCAT(homedir, maildir) AS home, CONCAT('maildir:', homedir, maildir) AS mail, uid, gid, CONCAT('*:storage=', quota, 'M') as quota_rule FROM mail_users WHERE (username = '%u' OR email = '%u')
+
+# If you wish to avoid two SQL lookups (passdb + userdb), you can use
+# userdb prefetch instead of userdb sql in dovecot.conf. In that case you'll
+# also have to return userdb fields in password_query prefixed with "userdb_"
+# string. For example:
+#password_query = \
+# SELECT userid AS user, password, \
+# home AS userdb_home, uid AS userdb_uid, gid AS userdb_gid \
+# FROM users WHERE userid = '%u'
+password_query = SELECT username AS user, password_enc AS password, CONCAT(homedir, maildir) AS userdb_home, uid AS userdb_uid, gid AS userdb_gid, CONCAT('maildir:', homedir, maildir) AS userdb_mail, CONCAT('*:storage=', quota, 'M') as userdb_quota_rule FROM mail_users WHERE (username = '%u' OR email = '%u') AND ((imap = 1 AND '%Ls' = 'imap') OR (pop3 = 1 AND '%Ls' = 'pop3') OR ((postfix = 'Y' AND '%Ls' = 'smtp') OR (postfix = 'Y' AND '%Ls' = 'sieve')))
+
+# Query to get a list of all usernames.
+iterate_query = "SELECT username AS user FROM mail_users WHERE (imap = 1 OR pop3 = 1)"
+]]>
+
+
+
+ to characters. For example "#@/@" means
+# that '#' and '/' characters are translated to '@'.
+#auth_username_translation =
+
+# Username formatting before it's looked up from databases. You can use
+# the standard variables here, eg. %Lu would lowercase the username, %n would
+# drop away the domain if it was given, or "%n-AT-%d" would change the '@' into
+# "-AT-". This translation is done after auth_username_translation changes.
+#auth_username_format = %Lu
+
+# If you want to allow master users to log in by specifying the master
+# username within the normal username string (ie. not using SASL mechanism's
+# support for it), you can specify the separator character here. The format
+# is then . UW-IMAP uses "*" as the
+# separator, so that could be a good choice.
+#auth_master_user_separator =
+
+# Username to use for users logging in with ANONYMOUS SASL mechanism
+#auth_anonymous_username = anonymous
+
+# Maximum number of dovecot-auth worker processes. They're used to execute
+# blocking passdb and userdb queries (eg. MySQL and PAM). They're
+# automatically created and destroyed as needed.
+#auth_worker_max_count = 30
+
+# Host name to use in GSSAPI principal names. The default is to use the
+# name returned by gethostname(). Use "$ALL" (with quotes) to allow all keytab
+# entries.
+#auth_gssapi_hostname =
+
+# Kerberos keytab to use for the GSSAPI mechanism. Will use the system
+# default (usually /etc/krb5.keytab) if not specified. You may need to change
+# the auth service to run as root to be able to read this file.
+#auth_krb5_keytab =
+
+# Do NTLM and GSS-SPNEGO authentication using Samba's winbind daemon and
+# ntlm_auth helper.
+#auth_use_winbind = no
+
+# Path for Samba's ntlm_auth helper binary.
+#auth_winbind_helper_path = /usr/bin/ntlm_auth
+
+# Time to delay before replying to failed authentications.
+#auth_failure_delay = 2 secs
+
+# Require a valid SSL client certificate or the authentication fails.
+#auth_ssl_require_client_cert = no
+
+# Take the username from client's SSL certificate, using
+# X509_NAME_get_text_by_NID() which returns the subject's DN's
+# CommonName.
+#auth_ssl_username_from_cert = no
+
+# Space separated list of wanted authentication mechanisms:
+# plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp skey
+# gss-spnego
+# NOTE: See also disable_plaintext_auth setting.
+auth_mechanisms = plain login
+
+##
+## Password and user databases
+##
+
+#
+# Password database is used to verify user's password (and nothing more).
+# You can have multiple passdbs and userdbs. This is useful if you want to
+# allow both system users (/etc/passwd) and virtual users to login without
+# duplicating the system users into virtual database.
+#
+#
+#
+# User database specifies where mails are located and what user/group IDs
+# own them. For single-UID configuration use "static" userdb.
+#
+#
+
+#!include auth-deny.conf.ext
+#!include auth-master.conf.ext
+
+#!include auth-system.conf.ext
+!include auth-sql.conf.ext
+#!include auth-ldap.conf.ext
+#!include auth-passwdfile.conf.ext
+#!include auth-checkpassword.conf.ext
+#!include auth-vpopmail.conf.ext
+#!include auth-static.conf.ext
+]]>
+
+
+
+
+#
+mail_location = mbox:~/mail:INBOX=/var/mail/%u
+
+# If you need to set multiple mailbox locations or want to change default
+# namespace settings, you can do it by defining namespace sections.
+#
+# You can have private, shared and public namespaces. Private namespaces
+# are for user's personal mails. Shared namespaces are for accessing other
+# users' mailboxes that have been shared. Public namespaces are for shared
+# mailboxes that are managed by sysadmin. If you create any shared or public
+# namespaces you'll typically want to enable ACL plugin also, otherwise all
+# users can access all the shared mailboxes, assuming they have permissions
+# on filesystem level to do so.
+namespace inbox {
+ # Namespace type: private, shared or public
+ #type = private
+
+ # Hierarchy separator to use. You should use the same separator for all
+ # namespaces or some clients get confused. '/' is usually a good one.
+ # The default however depends on the underlying mail storage format.
+ #separator =
+
+ # Prefix required to access this namespace. This needs to be different for
+ # all namespaces. For example "Public/".
+ #prefix =
+
+ # Physical location of the mailbox. This is in same format as
+ # mail_location, which is also the default for it.
+ #location =
+
+ # There can be only one INBOX, and this setting defines which namespace
+ # has it.
+ inbox = yes
+
+ # If namespace is hidden, it's not advertised to clients via NAMESPACE
+ # extension. You'll most likely also want to set list=no. This is mostly
+ # useful when converting from another server with different namespaces which
+ # you want to deprecate but still keep working. For example you can create
+ # hidden namespaces with prefixes "~/mail/", "~%u/mail/" and "mail/".
+ #hidden = no
+
+ # Show the mailboxes under this namespace with LIST command. This makes the
+ # namespace visible for clients that don't support NAMESPACE extension.
+ # "children" value lists child mailboxes, but hides the namespace prefix.
+ #list = yes
+
+ # Namespace handles its own subscriptions. If set to "no", the parent
+ # namespace handles them (empty prefix should always have this as "yes")
+ #subscriptions = yes
+}
+
+# Example shared namespace configuration
+#namespace {
+ #type = shared
+ #separator = /
+
+ # Mailboxes are visible under "shared/user@domain/"
+ # %%n, %%d and %%u are expanded to the destination user.
+ #prefix = shared/%%u/
+
+ # Mail location for other users' mailboxes. Note that %variables and ~/
+ # expands to the logged in user's data. %%n, %%d, %%u and %%h expand to the
+ # destination user's data.
+ #location = maildir:%%h/Maildir:INDEX=~/Maildir/shared/%%u
+
+ # Use the default namespace for saving subscriptions.
+ #subscriptions = no
+
+ # List the shared/ namespace only if there are visible shared mailboxes.
+ #list = children
+#}
+# Should shared INBOX be visible as "shared/user" or "shared/user/INBOX"?
+#mail_shared_explicit_inbox = no
+
+# System user and group used to access mails. If you use multiple, userdb
+# can override these by returning uid or gid fields. You can use either numbers
+# or names.
+#mail_uid =
+#mail_gid =
+
+# Group to enable temporarily for privileged operations. Currently this is
+# used only with INBOX when either its initial creation or dotlocking fails.
+# Typically this is set to "mail" to give access to /var/mail.
+#mail_privileged_group =
+
+# Grant access to these supplementary groups for mail processes. Typically
+# these are used to set up access to shared mailboxes. Note that it may be
+# dangerous to set these if users can create symlinks (e.g. if "mail" group is
+# set here, ln -s /var/mail ~/mail/var could allow a user to delete others'
+# mailboxes, or ln -s /secret/shared/box ~/mail/mybox would allow reading it).
+mail_access_groups = vmail
+
+# Allow full filesystem access to clients. There's no access checks other than
+# what the operating system does for the active UID/GID. It works with both
+# maildir and mboxes, allowing you to prefix mailboxes names with eg. /path/
+# or ~user/.
+#mail_full_filesystem_access = no
+
+# Dictionary for key=value mailbox attributes. Currently used by URLAUTH, but
+# soon intended to be used by METADATA as well.
+#mail_attribute_dict =
+
+##
+## Mail processes
+##
+
+# Don't use mmap() at all. This is required if you store indexes to shared
+# filesystems (NFS or clustered filesystem).
+#mmap_disable = no
+
+# Rely on O_EXCL to work when creating dotlock files. NFS supports O_EXCL
+# since version 3, so this should be safe to use nowadays by default.
+#dotlock_use_excl = yes
+
+# When to use fsync() or fdatasync() calls:
+# optimized (default): Whenever necessary to avoid losing important data
+# always: Useful with e.g. NFS when write()s are delayed
+# never: Never use it (best performance, but crashes can lose data)
+#mail_fsync = optimized
+
+# Locking method for index files. Alternatives are fcntl, flock and dotlock.
+# Dotlocking uses some tricks which may create more disk I/O than other locking
+# methods. NFS users: flock doesn't work, remember to change mmap_disable.
+#lock_method = fcntl
+
+# Directory in which LDA/LMTP temporarily stores incoming mails >128 kB.
+#mail_temp_dir = /tmp
+
+# Valid UID range for users, defaults to 500 and above. This is mostly
+# to make sure that users can't log in as daemons or other system users.
+# Note that denying root logins is hardcoded to dovecot binary and can't
+# be done even if first_valid_uid is set to 0.
+#first_valid_uid = 500
+#last_valid_uid = 0
+
+# Valid GID range for users, defaults to non-root/wheel. Users having
+# non-valid GID as primary group ID aren't allowed to log in. If user
+# belongs to supplementary groups with non-valid GIDs, those groups are
+# not set.
+#first_valid_gid = 1
+#last_valid_gid = 0
+
+# Maximum allowed length for mail keyword name. It's only forced when trying
+# to create new keywords.
+#mail_max_keyword_length = 50
+
+# ':' separated list of directories under which chrooting is allowed for mail
+# processes (ie. /var/mail will allow chrooting to /var/mail/foo/bar too).
+# This setting doesn't affect login_chroot, mail_chroot or auth chroot
+# settings. If this setting is empty, "/./" in home dirs are ignored.
+# WARNING: Never add directories here which local users can modify, that
+# may lead to root exploit. Usually this should be done only if you don't
+# allow shell access for users.
+#valid_chroot_dirs =
+
+# Default chroot directory for mail processes. This can be overridden for
+# specific users in user database by giving /./ in user's home directory
+# (eg. /home/./user chroots into /home). Note that usually there is no real
+# need to do chrooting, Dovecot doesn't allow users to access files outside
+# their mail directory anyway. If your home directories are prefixed with
+# the chroot directory, append "/." to mail_chroot.
+#mail_chroot =
+
+# UNIX socket path to master authentication server to find users.
+# This is used by imap (for shared users) and lda.
+#auth_socket_path = /var/run/dovecot/auth-userdb
+
+# Directory where to look up mail plugins.
+#mail_plugin_dir = /usr/lib/dovecot/modules
+
+# Space separated list of plugins to load for all services. Plugins specific to
+# IMAP, LDA, etc. are added to this list in their own .conf files.
+#mail_plugins =
+
+##
+## Mailbox handling optimizations
+##
+
+# Mailbox list indexes can be used to optimize IMAP STATUS commands. They are
+# also required for IMAP NOTIFY extension to be enabled.
+#mailbox_list_index = no
+
+# The minimum number of mails in a mailbox before updates are done to cache
+# file. This allows optimizing Dovecot's behavior to do less disk writes at
+# the cost of more disk reads.
+#mail_cache_min_mail_count = 0
+
+# When IDLE command is running, mailbox is checked once in a while to see if
+# there are any new mails or other changes. This setting defines the minimum
+# time to wait between those checks. Dovecot can also use dnotify, inotify and
+# kqueue to find out immediately when changes occur.
+#mailbox_idle_check_interval = 30 secs
+
+# Save mails with CR+LF instead of plain LF. This makes sending those mails
+# take less CPU, especially with sendfile() syscall with Linux and FreeBSD.
+# But it also creates a bit more disk I/O which may just make it slower.
+# Also note that if other software reads the mboxes/maildirs, they may handle
+# the extra CRs wrong and cause problems.
+#mail_save_crlf = no
+
+# Max number of mails to keep open and prefetch to memory. This only works with
+# some mailbox formats and/or operating systems.
+#mail_prefetch_count = 0
+
+# How often to scan for stale temporary files and delete them (0 = never).
+# These should exist only after Dovecot dies in the middle of saving mails.
+#mail_temp_scan_interval = 1w
+
+##
+## Maildir-specific settings
+##
+
+# By default LIST command returns all entries in maildir beginning with a dot.
+# Enabling this option makes Dovecot return only entries which are directories.
+# This is done by stat()ing each entry, so it causes more disk I/O.
+# (For systems setting struct dirent->d_type, this check is free and it's
+# done always regardless of this setting)
+#maildir_stat_dirs = no
+
+# When copying a message, do it with hard links whenever possible. This makes
+# the performance much better, and it's unlikely to have any side effects.
+#maildir_copy_with_hardlinks = yes
+
+# Assume Dovecot is the only MUA accessing Maildir: Scan cur/ directory only
+# when its mtime changes unexpectedly or when we can't find the mail otherwise.
+#maildir_very_dirty_syncs = no
+
+# If enabled, Dovecot doesn't use the S= in the Maildir filenames for
+# getting the mail's physical size, except when recalculating Maildir++ quota.
+# This can be useful in systems where a lot of the Maildir filenames have a
+# broken size. The performance hit for enabling this is very small.
+#maildir_broken_filename_sizes = no
+
+# Always move mails from new/ directory to cur/, even when the \Recent flags
+# aren't being reset.
+#maildir_empty_new = no
+
+##
+## mbox-specific settings
+##
+
+# Which locking methods to use for locking mbox. There are four available:
+# dotlock: Create .lock file. This is the oldest and most NFS-safe
+# solution. If you want to use /var/mail/ like directory, the users
+# will need write access to that directory.
+# dotlock_try: Same as dotlock, but if it fails because of permissions or
+# because there isn't enough disk space, just skip it.
+# fcntl : Use this if possible. Works with NFS too if lockd is used.
+# flock : May not exist in all systems. Doesn't work with NFS.
+# lockf : May not exist in all systems. Doesn't work with NFS.
+#
+# You can use multiple locking methods; if you do the order they're declared
+# in is important to avoid deadlocks if other MTAs/MUAs are using multiple
+# locking methods as well. Some operating systems don't allow using some of
+# them simultaneously.
+#
+# The Debian value for mbox_write_locks differs from upstream Dovecot. It is
+# changed to be compliant with Debian Policy (section 11.6) for NFS safety.
+# Dovecot: mbox_write_locks = dotlock fcntl
+# Debian: mbox_write_locks = fcntl dotlock
+#
+#mbox_read_locks = fcntl
+#mbox_write_locks = fcntl dotlock
+
+# Maximum time to wait for lock (all of them) before aborting.
+#mbox_lock_timeout = 5 mins
+
+# If dotlock exists but the mailbox isn't modified in any way, override the
+# lock file after this much time.
+#mbox_dotlock_change_timeout = 2 mins
+
+# When mbox changes unexpectedly we have to fully read it to find out what
+# changed. If the mbox is large this can take a long time. Since the change
+# is usually just a newly appended mail, it'd be faster to simply read the
+# new mails. If this setting is enabled, Dovecot does this but still safely
+# fallbacks to re-reading the whole mbox file whenever something in mbox isn't
+# how it's expected to be. The only real downside to this setting is that if
+# some other MUA changes message flags, Dovecot doesn't notice it immediately.
+# Note that a full sync is done with SELECT, EXAMINE, EXPUNGE and CHECK
+# commands.
+#mbox_dirty_syncs = yes
+
+# Like mbox_dirty_syncs, but don't do full syncs even with SELECT, EXAMINE,
+# EXPUNGE or CHECK commands. If this is set, mbox_dirty_syncs is ignored.
+#mbox_very_dirty_syncs = no
+
+# Delay writing mbox headers until doing a full write sync (EXPUNGE and CHECK
+# commands and when closing the mailbox). This is especially useful for POP3
+# where clients often delete all mails. The downside is that our changes
+# aren't immediately visible to other MUAs.
+#mbox_lazy_writes = yes
+
+# If mbox size is smaller than this (e.g. 100k), don't write index files.
+# If an index file already exists it's still read, just not updated.
+#mbox_min_index_size = 0
+
+# Mail header selection algorithm to use for MD5 POP3 UIDLs when
+# pop3_uidl_format=%m. For backwards compatibility we use apop3d inspired
+# algorithm, but it fails if the first Received: header isn't unique in all
+# mails. An alternative algorithm is "all" that selects all headers.
+#mbox_md5 = apop3d
+
+##
+## mdbox-specific settings
+##
+
+# Maximum dbox file size until it's rotated.
+#mdbox_rotate_size = 2M
+
+# Maximum dbox file age until it's rotated. Typically in days. Day begins
+# from midnight, so 1d = today, 2d = yesterday, etc. 0 = check disabled.
+#mdbox_rotate_interval = 0
+
+# When creating new mdbox files, immediately preallocate their size to
+# mdbox_rotate_size. This setting currently works only in Linux with some
+# filesystems (ext4, xfs).
+#mdbox_preallocate_space = no
+
+##
+## Mail attachments
+##
+
+# sdbox and mdbox support saving mail attachments to external files, which
+# also allows single instance storage for them. Other backends don't support
+# this for now.
+
+# Directory root where to store mail attachments. Disabled, if empty.
+#mail_attachment_dir =
+
+# Attachments smaller than this aren't saved externally. It's also possible to
+# write a plugin to disable saving specific attachments externally.
+#mail_attachment_min_size = 128k
+
+# Filesystem backend to use for saving attachments:
+# posix : No SiS done by Dovecot (but this might help FS's own deduplication)
+# sis posix : SiS with immediate byte-by-byte comparison during saving
+# sis-queue posix : SiS with delayed comparison and deduplication
+#mail_attachment_fs = sis posix
+
+# Hash format to use in attachment filenames. You can add any text and
+# variables: %{md4}, %{md5}, %{sha1}, %{sha256}, %{sha512}, %{size}.
+# Variables can be truncated, e.g. %{sha256:80} returns only first 80 bits
+#mail_attachment_hash = %{sha1}
+]]>
+
+
+
+
+ #service_count = 1
+
+ # Number of processes to always keep waiting for more connections.
+ #process_min_avail = 0
+
+ # If you set service_count=0, you probably need to grow this.
+ #vsz_limit = $default_vsz_limit
+}
+
+service pop3-login {
+ inet_listener pop3 {
+ #port = 110
+ }
+ inet_listener pop3s {
+ #port = 995
+ #ssl = yes
+ }
+}
+
+service lmtp {
+ unix_listener lmtp {
+ #mode = 0666
+ }
+
+ # Create inet listener only if you can't use the above UNIX socket
+ #inet_listener lmtp {
+ # Avoid making LMTP visible for the entire internet
+ #address =
+ #port =
+ #}
+}
+
+service imap {
+ # Most of the memory goes to mmap()ing files. You may need to increase this
+ # limit if you have huge mailboxes.
+ #vsz_limit = $default_vsz_limit
+
+ # Max. number of IMAP processes (connections)
+ #process_limit = 1024
+}
+
+service pop3 {
+ # Max. number of POP3 processes (connections)
+ #process_limit = 1024
+}
+
+service auth {
+ # auth_socket_path points to this userdb socket by default. It's typically
+ # used by dovecot-lda, doveadm, possibly imap process, etc. Users that have
+ # full permissions to this socket are able to get a list of all usernames and
+ # get the results of everyone's userdb lookups.
+ #
+ # The default 0666 mode allows anyone to connect to the socket, but the
+ # userdb lookups will succeed only if the userdb returns an "uid" field that
+ # matches the caller process's UID. Also if caller's uid or gid matches the
+ # socket's uid or gid the lookup succeeds. Anything else causes a failure.
+ #
+ # To give the caller full permissions to lookup all users, set the mode to
+ # something else than 0666 and Dovecot lets the kernel enforce the
+ # permissions (e.g. 0777 allows everyone full permissions).
+ unix_listener auth-userdb {
+ #mode = 0666
+ #user =
+ #group =
+ }
+
+ # Postfix smtp-auth
+ unix_listener /var/spool/postfix/private/auth {
+ mode = 0660
+ user = postfix
+ group = postfix
+ }
+
+ # Exim4 smtp-auth
+ unix_listener auth-client {
+ mode = 0660
+ user = mail
+ # group = Debian-exim
+ }
+
+ # Auth process is run as this user.
+ #user = $default_internal_user
+}
+
+service auth-worker {
+ # Auth worker process is run as root by default, so that it can access
+ # /etc/shadow. If this isn't necessary, the user should be changed to
+ # $default_internal_user.
+ #user = root
+}
+
+service dict {
+ # If dict proxy is used, mail processes should have access to its socket.
+ # For example: mode=0660, group=vmail and global mail_access_groups=vmail
+ unix_listener dict {
+ #mode = 0600
+ #user =
+ #group =
+ }
+}
+]]>
+
+
+
+
+ssl = yes
+
+# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
+# dropping root privileges, so keep the key file unreadable by anyone but
+# root. Included doc/mkcert.sh can be used to easily generate self-signed
+# certificate, just make sure to update the domains in dovecot-openssl.cnf
+ssl_cert = <
+ssl_key = <
+
+# If key file is password protected, give the password here. Alternatively
+# give it when starting dovecot with -p parameter. Since this file is often
+# world-readable, you may want to place this setting instead to a different
+# root owned 0600 file by using ssl_key_password =
+
+
+
+ . %d expands to recipient domain.
+postmaster_address = postmaster@
+
+# Hostname to use in various parts of sent mails (e.g. in Message-Id) and
+# in LMTP replies. Default is the system's real hostname@domain.
+#hostname =
+
+# If user is over quota, return with temporary failure instead of
+# bouncing the mail.
+#quota_full_tempfail = no
+
+# Binary to use for sending mails.
+#sendmail_path = /usr/sbin/sendmail
+
+# If non-empty, send mails via this SMTP host[:port] instead of sendmail.
+#submission_host =
+
+# Subject: header to use for rejection mails. You can use the same variables
+# as for rejection_reason below.
+#rejection_subject = Rejected: %s
+
+# Human readable error message for rejection mails. You can use variables:
+# %n = CRLF, %r = reason, %s = original subject, %t = recipient
+#rejection_reason = Your message to <%t> was automatically rejected:%n%r
+
+# Delimiter character between local-part and detail in email address.
+#recipient_delimiter = +
+
+# Header where the original recipient address (SMTP's RCPT TO: address) is taken
+# from if not available elsewhere. With dovecot-lda -a parameter overrides this.
+# A commonly used header for this is X-Original-To.
+#lda_original_recipient_header =
+
+# Should saving a mail to a nonexistent mailbox automatically create it?
+#lda_mailbox_autocreate = no
+
+# Should automatically created mailboxes be also automatically subscribed?
+#lda_mailbox_autosubscribe = no
+
+protocol lda {
+ # Space separated list of plugins to load (default is global mail_plugins).
+ mail_plugins = $mail_plugins quota sieve
+}
+]]>
+
+
+
+
+
+
+
+
+ #service_count = 1
+
+ # Number of processes to always keep waiting for more connections.
+ #process_min_avail = 0
+
+ # If you set service_count=0, you probably need to grow this.
+ #vsz_limit = 64M
+#}
+
+#service managesieve {
+ # Max. number of ManageSieve processes (connections)
+ #process_limit = 1024
+#}
+
+# Service configuration
+
+protocol sieve {
+ # Maximum ManageSieve command line length in bytes. ManageSieve usually does
+ # not involve overly long command lines, so this setting will not normally
+ # need adjustment
+ #managesieve_max_line_length = 65536
+
+ # Maximum number of ManageSieve connections allowed for a user from each IP
+ # address.
+ # NOTE: The username is compared case-sensitively.
+ #mail_max_userip_connections = 10
+
+ # Space separated list of plugins to load (none known to be useful so far).
+ # Do NOT try to load IMAP plugins here.
+ #mail_plugins =
+
+ # MANAGESIEVE logout format string:
+ # %i - total number of bytes read from client
+ # %o - total number of bytes sent to client
+ #managesieve_logout_format = bytes=%i/%o
+
+ # To fool ManageSieve clients that are focused on CMU's timesieved you can
+ # specify the IMPLEMENTATION capability that Dovecot reports to clients.
+ # For example: 'Cyrus timsieved v2.2.13'
+ #managesieve_implementation_string = Dovecot Pigeonhole
+
+ # Explicitly specify the SIEVE and NOTIFY capability reported by the server
+ # before login. If left unassigned these will be reported dynamically
+ # according to what the Sieve interpreter supports by default (after login
+ # this may differ depending on the user).
+ #managesieve_sieve_capability =
+ #managesieve_notify_capability =
+
+ # The maximum number of compile errors that are returned to the client upon
+ # script upload or script verification.
+ #managesieve_max_compile_errors = 5
+
+ # Refer to 90-sieve.conf for script quota configuration and configuration of
+ # Sieve execution limits.
+}
+]]>
+
+
+
+ = 2.1.4) : %v.%u
+# Dovecot v0.99.x : %v.%u
+# tpop3d : %Mf
+#
+# Note that Outlook 2003 seems to have problems with %v.%u format which was
+# Dovecot's default, so if you're building a new server it would be a good
+# idea to change this. %08Xu%08Xv should be pretty fail-safe.
+#
+#pop3_uidl_format = %08Xu%08Xv
+
+# Permanently save UIDLs sent to POP3 clients, so pop3_uidl_format changes
+# won't change those UIDLs. Currently this works only with Maildir.
+#pop3_save_uidl = no
+
+# What to do about duplicate UIDLs if they exist?
+# allow: Show duplicates to clients.
+# rename: Append a temporary -2, -3, etc. counter after the UIDL.
+#pop3_uidl_duplicates = allow
+
+# This option changes POP3 behavior so that it's not possible to actually
+# delete mails via POP3, only hide them from future POP3 sessions. The mails
+# will still be counted towards user's quota until actually deleted via IMAP.
+# Use e.g. "$POP3Deleted" as the value (it will be visible as IMAP keyword).
+# Make sure you can legally archive mails before enabling this setting.
+#pop3_deleted_flag =
+
+# POP3 logout format string:
+# %i - total number of bytes read from client
+# %o - total number of bytes sent to client
+# %t - number of TOP commands
+# %p - number of bytes sent to client as a result of TOP command
+# %r - number of RETR commands
+# %b - number of bytes sent to client as a result of RETR command
+# %d - number of deleted messages
+# %m - number of messages (before deletion)
+# %s - mailbox size in bytes (before deletion)
+# %u - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly
+pop3_logout_format = in=%i out=%o top=%t/%p, retr=%r/%b, del=%d/%m, size=%s
+
+# Workarounds for various client bugs:
+# outlook-no-nuls:
+# Outlook and Outlook Express hang if mails contain NUL characters.
+# This setting replaces them with 0x80 character.
+# oe-ns-eoh:
+# Outlook Express and Netscape Mail breaks if end of headers-line is
+# missing. This option simply sends it if it's missing.
+# The list is space-separated.
+#pop3_client_workarounds =
+
+protocol pop3 {
+ # Space separated list of plugins to load (default is global mail_plugins).
+ #mail_plugins = $mail_plugins
+
+ # Maximum number of POP3 connections allowed for a user from each IP address.
+ # NOTE: The username is compared case-sensitively.
+ #mail_max_userip_connections = 10
+}
+]]>
+
+
+
+ See sieve_before fore executing scripts before the user's personal
+ # script.
+ #sieve_default = /var/lib/dovecot/sieve/default.sieve
+
+ # Directory for :personal include scripts for the include extension. This
+ # is also where the ManageSieve service stores the user's scripts.
+ sieve_dir = ~/sieve
+
+ # Directory for :global include scripts for the include extension.
+ #sieve_global_dir =
+
+ # Path to a script file or a directory containing script files that need to be
+ # executed before the user's script. If the path points to a directory, all
+ # the Sieve scripts contained therein (with the proper .sieve extension) are
+ # executed. The order of execution within a directory is determined by the
+ # file names, using a normal 8bit per-character comparison. Multiple script
+ # file or directory paths can be specified by appending an increasing number.
+ #sieve_before =
+ #sieve_before2 =
+ #sieve_before3 = (etc...)
+
+ # Identical to sieve_before, only the specified scripts are executed after the
+ # user's script (only when keep is still in effect!). Multiple script file or
+ # directory paths can be specified by appending an increasing number.
+ #sieve_after =
+ #sieve_after2 =
+ #sieve_after2 = (etc...)
+
+ # Which Sieve language extensions are available to users. By default, all
+ # supported extensions are available, except for deprecated extensions or
+ # those that are still under development. Some system administrators may want
+ # to disable certain Sieve extensions or enable those that are not available
+ # by default. This setting can use '+' and '-' to specify differences relative
+ # to the default. For example `sieve_extensions = +imapflags' will enable the
+ # deprecated imapflags extension in addition to all extensions were already
+ # enabled by default.
+ #sieve_extensions = +notify +imapflags
+
+ # Which Sieve language extensions are ONLY available in global scripts. This
+ # can be used to restrict the use of certain Sieve extensions to administrator
+ # control, for instance when these extensions can cause security concerns.
+ # This setting has higher precedence than the `sieve_extensions' setting
+ # (above), meaning that the extensions enabled with this setting are never
+ # available to the user's personal script no matter what is specified for the
+ # `sieve_extensions' setting. The syntax of this setting is similar to the
+ # `sieve_extensions' setting, with the difference that extensions are
+ # enabled or disabled for exclusive use in global scripts. Currently, no
+ # extensions are marked as such by default.
+ #sieve_global_extensions =
+
+ # The Pigeonhole Sieve interpreter can have plugins of its own. Using this
+ # setting, the used plugins can be specified. Check the Dovecot wiki
+ # (wiki2.dovecot.org) or the pigeonhole website
+ # (http://pigeonhole.dovecot.org) for available plugins.
+ # The sieve_extprograms plugin is included in this release.
+ #sieve_plugins =
+
+ # The separator that is expected between the :user and :detail
+ # address parts introduced by the subaddress extension. This may
+ # also be a sequence of characters (e.g. '--'). The current
+ # implementation looks for the separator from the left of the
+ # localpart and uses the first one encountered. The :user part is
+ # left of the separator and the :detail part is right. This setting
+ # is also used by Dovecot's LMTP service.
+ #recipient_delimiter = +
+
+ # The maximum size of a Sieve script. The compiler will refuse to compile any
+ # script larger than this limit. If set to 0, no limit on the script size is
+ # enforced.
+ #sieve_max_script_size = 1M
+
+ # The maximum number of actions that can be performed during a single script
+ # execution. If set to 0, no limit on the total number of actions is enforced.
+ #sieve_max_actions = 32
+
+ # The maximum number of redirect actions that can be performed during a single
+ # script execution. If set to 0, no redirect actions are allowed.
+ #sieve_max_redirects = 4
+
+ # The maximum number of personal Sieve scripts a single user can have. If set
+ # to 0, no limit on the number of scripts is enforced.
+ # (Currently only relevant for ManageSieve)
+ #sieve_quota_max_scripts = 0
+
+ # The maximum amount of disk storage a single user's scripts may occupy. If
+ # set to 0, no limit on the used amount of disk storage is enforced.
+ # (Currently only relevant for ManageSieve)
+ #sieve_quota_max_storage = 0
+}
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ //service[@type='mail']/general/installs[@index=1]
+
+ //service[@type='mail']/general/files[@index=1]
+
+ //service[@type='mail']/general/commands[@index=1]
+
+
+
+
+
+
+
+
+
+ /dev/null]]>
+ /etc/apt/sources.list.d/rspamd.list]]>
+ > /etc/apt/sources.list.d/rspamd.list]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ //service[@type='antispam']/general/commands[@index=1]
+
+ //service[@type='antispam']/general/installs[@index=1]
+
+ //service[@type='antispam']/general/commands[@index=2]
+
+ //service[@type='antispam']/general/files[@index=1]
+
+ //service[@type='antispam']/general/commands[@index=3]
+
+
+
+
+
+
+
+
+
+ "
+[ -f /etc/ssl/certs/proftpd_ec.crt ] || openssl req -new -x509 -nodes -newkey ec:<(openssl ecparam -name secp521r1) -keyout /etc/ssl/private/proftpd_ec.key -out /etc/ssl/certs/proftpd_ec.crt -days 3650 -subj "/C=US/ST=Some-State/O=Internet Widgits Pty Ltd/CN="
+chmod 0600 /etc/ssl/private/proftpd.key /etc/ssl/private/proftpd_ec.key
+]]>
+
+
+
+
+
+
+
+
+ IdentLookups off
+
+
+ServerName " FTP Server"
+ServerType standalone
+DeferWelcome off
+
+DefaultServer on
+ShowSymlinks on
+
+TimeoutNoTransfer 600
+TimeoutStalled 600
+TimeoutIdle 1200
+
+DisplayLogin welcome.msg
+DisplayChdir .message true
+ListOptions "-l"
+
+DenyFilter \*.*/
+
+# Use this to jail all users in their homes
+# DefaultRoot ~
+
+# Users require a valid shell listed in /etc/shells to login.
+# Use this directive to release that constrain.
+# RequireValidShell off
+
+# Port 21 is the standard FTP port.
+Port 21
+
+# In some cases you have to specify passive ports range to by-pass
+# firewall limitations. Ephemeral ports can be used for that, but
+# feel free to use a more narrow range.
+# PassivePorts 49152 65534
+
+# If your host was NATted, this option is useful in order to
+# allow passive transfers to work. You have to use your public
+# address and opening the passive ports used on your firewall as well.
+# MasqueradeAddress 1.2.3.4
+
+# This is useful for masquerading address with dynamic IPs:
+# refresh any configured MasqueradeAddress directives every 8 hours
+
+# DynMasqRefresh 28800
+
+
+# To prevent DoS attacks, set the maximum number of child processes
+# to 30. If you need to allow more than 30 concurrent connections
+# at once, simply increase this value. Note that this ONLY works
+# in standalone mode, in inetd mode you should use an inetd server
+# that allows you to limit maximum number of processes per service
+# (such as xinetd)
+MaxInstances 30
+
+# Set the user and group that the server normally runs at.
+User proftpd
+Group nogroup
+
+# Umask 022 is a good standard umask to prevent new files and dirs
+# (second parm) from being group and world writable.
+Umask 022 022
+# Normally, we want files to be overwritable.
+AllowOverwrite on
+
+# Uncomment this if you are using NIS or LDAP via NSS to retrieve passwords:
+# PersistentPasswd off
+
+# This is required to use both PAM-based authentication and local passwords
+# AuthOrder mod_auth_pam.c* mod_auth_unix.c
+
+# Be warned: use of this directive impacts CPU average load!
+# Uncomment this if you like to see progress and transfer rate with ftpwho
+# in downloads. That is not needed for uploads rates.
+#
+# UseSendFile off
+
+TransferLog /var/log/proftpd/xferlog
+SystemLog /var/log/proftpd/proftpd.log
+
+# Logging onto /var/log/lastlog is enabled but set to off by default
+#UseLastlog on
+
+# In order to keep log file dates consistent after chroot, use timezone info
+# from /etc/localtime. If this is not set, and proftpd is configured to
+# chroot (e.g. DefaultRoot or ), it will use the non-daylight
+# savings timezone regardless of whether DST is in effect.
+#SetEnv TZ :/etc/localtime
+
+
+QuotaEngine on
+
+
+
+Ratios off
+
+
+
+# Delay engine reduces impact of the so-called Timing Attack described in
+# http://www.securityfocus.com/bid/11430/discuss
+# It is on by default.
+
+DelayEngine on
+
+
+
+ControlsEngine off
+ControlsMaxClients 2
+ControlsLog /var/log/proftpd/controls.log
+ControlsInterval 5
+ControlsSocket /var/run/proftpd/proftpd.sock
+
+
+
+AdminControlsEngine off
+
+
+#
+# Alternative authentication frameworks
+#
+#Include /etc/proftpd/ldap.conf
+Include /etc/proftpd/sql.conf
+
+#
+# This is used for FTPS connections
+#
+Include /etc/proftpd/tls.conf
+
+#
+# Useful to keep VirtualHost/VirtualRoot directives separated
+#
+#Include /etc/proftpd/virtuals.conf
+
+# A basic anonymous configuration, no upload directories.
+
+#
+# User ftp
+# Group nogroup
+# # We want clients to be able to login with "anonymous" as well as "ftp"
+# UserAlias anonymous ftp
+# # Cosmetic changes, all files belongs to ftp user
+# DirFakeUser on ftp
+# DirFakeGroup on ftp
+#
+# RequireValidShell off
+#
+# # Limit the maximum number of anonymous logins
+# MaxClients 10
+#
+# # We want 'welcome.msg' displayed at login, and '.message' displayed
+# # in each newly chdired directory.
+# DisplayLogin welcome.msg
+# DisplayChdir .message
+#
+# # Limit WRITE everywhere in the anonymous chroot
+#
+#
+# DenyAll
+#
+#
+#
+# # Uncomment this if you're brave.
+# #
+# # # Umask 022 is a good standard umask to prevent new files and dirs
+# # # (second parm) from being group and world writable.
+# # Umask 022 022
+# #
+# # DenyAll
+# #
+# #
+# # AllowAll
+# #
+# #
+#
+#
+
+# Include other custom configuration files
+Include /etc/proftpd/conf.d/
+]]>
+
+
+
+
+
+
+
+
+
+DefaultRoot ~
+RequireValidShell off
+AuthOrder mod_sql.c
+
+#
+# Choose a SQL backend among MySQL or PostgreSQL.
+# Both modules are loaded in default configuration, so you have to specify the backend
+# or comment out the unused module in /etc/proftpd/modules.conf.
+# Use 'mysql' or 'postgres' as possible values.
+#
+SQLBackend mysql
+#
+SQLEngine on
+SQLAuthenticate on
+#
+# Use both an encrypted or plaintext password
+SQLAuthTypes Crypt OpenSSL
+
+SQLAuthenticate users* groups*
+
+#
+# Connection
+SQLConnectInfo @
+#
+# Describes both users/groups tables
+#
+SQLUserInfo ftp_users username password uid gid homedir shell
+SQLGroupInfo ftp_groups groupname gid members
+#
+SQLUserWhereClause "login_enabled = 'y'"
+
+SQLLog PASS login
+SQLNamedQuery login UPDATE "last_login=now(), login_count=login_count+1 WHERE username='%u'" ftp_users
+
+SQLLog RETR download
+SQLNamedQuery download UPDATE "down_count=down_count+1, down_bytes=down_bytes+%b WHERE username='%u'" ftp_users
+
+SQLLog STOR upload
+SQLNamedQuery upload UPDATE "up_count=up_count+1, up_bytes=up_bytes+%b WHERE username='%u'" ftp_users
+
+QuotaEngine on
+QuotaShowQuotas on
+QuotaDisplayUnits Mb
+QuotaLock /var/lock/ftpd.quotatab.lock
+QuotaLimitTable sql:/get-quota-limit
+QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally
+SQLNamedQuery get-quota-limit SELECT "ftp_users.username AS name, ftp_quotalimits.quota_type, ftp_quotalimits.per_session, ftp_quotalimits.limit_type, panel_customers.diskspace*1024 AS bytes_in_avail, ftp_quotalimits.bytes_out_avail, ftp_quotalimits.bytes_xfer_avail, ftp_quotalimits.files_in_avail, ftp_quotalimits.files_out_avail, ftp_quotalimits.files_xfer_avail FROM ftp_users, ftp_quotalimits, panel_customers WHERE ftp_users.username = '%{0}' AND panel_customers.loginname = SUBSTRING_INDEX('%{0}', 'ftp', 1) AND quota_type ='%{1}'"
+SQLNamedQuery get-quota-tally SELECT "name, quota_type, bytes_in_used,bytes_out_used, bytes_xfer_used, files_in_used, files_out_used,files_xfer_used FROM ftp_quotatallies WHERE name = '%{0}' AND quota_type = '%{1}'"
+SQLNamedQuery update-quota-tally UPDATE "bytes_in_used = bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, files_in_used = files_in_used + %{3}, files_out_used= files_out_used + %{4}, files_xfer_used = files_xfer_used + %{5} WHERE name= '%{6}' AND quota_type = '%{7}'" ftp_quotatallies
+SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4},%{5}, %{6}, %{7}" ftp_quotatallies
+
+]]>
+
+
+
+
+TLSEngine on
+TLSLog /var/log/proftpd/tls.log
+TLSProtocol TLSv1.2 TLSv1.3
+TLSRSACertificateFile /etc/ssl/certs/proftpd.crt
+TLSRSACertificateKeyFile /etc/ssl/private/proftpd.key
+TLSECCertificateFile /etc/ssl/certs/proftpd_ec.crt
+TLSECCertificateKeyFile /etc/ssl/private/proftpd_ec.key
+# TLSCACertificateFile
+TLSOptions NoSessionReuseRequired
+TLSVerifyClient off
+
+# Are clients required to use FTP over TLS when talking to this server?
+TLSRequired on
+
+# Allow SSL/TLS renegotiations when the client requests them, but
+# do not force the renegotiations. Some clients do not support
+# SSL/TLS renegotiations; when mod_tls forces a renegotiation, these
+# clients will close the data connection, or there will be a timeout
+# on an idle data connection.
+#
+#TLSRenegotiate required off
+
+]]>
+
+
+
+
+From 127.0.0.1
+
+
+MaxLoginAttempts 3
+
+
+ BanEngine off
+
+
+ BanEngine on
+
+BanLog /var/log/proftpd/ban.log
+BanTable /etc/proftpd/ban.tab
+BanMessage "User %u was banned."
+BanOnEvent ClientConnectRate 5/00:00:02 12:00:00 "Stop connecting frequently"
+BanOnEvent MaxLoginAttempts 3/00:30:00 12:00:00
+BanOnEvent AnonRejectPasswords 1/01:00:00 99:99:99
+BanControlsACLs all allow user root
+
+
+
+BanEngine off
+DelayEngine off
+
+ ]]>
+
+
+
+
+
+
+
+
+ "
+openssl dhparam -out /etc/ssl/private/pure-ftpd-dhparams.pem 3072
+chmod 0600 /etc/ssl/private/pure-ftpd.pem /etc/ssl/private/pure-ftpd-dhparams.pem
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Mandatory : user password. You must have a password.
+
+MYSQLPassword
+
+
+# Mandatory : database to open.
+
+MYSQLDatabase
+
+
+# Mandatory : how passwords are stored
+# Valid values are : "cleartext", "crypt", "sha1", "md5" and "password"
+# ("password" = MySQL password() function)
+# You can also use "any" to try "crypt", "sha1", "md5" *and* "password"
+
+MYSQLCrypt any
+
+
+# In the following directives, parts of the strings are replaced at
+# run-time before performing queries :
+#
+# \L is replaced by the login of the user trying to authenticate.
+# \I is replaced by the IP address the user connected to.
+# \P is replaced by the port number the user connected to.
+# \R is replaced by the IP address the user connected from.
+# \D is replaced by the remote IP address, as a long decimal number.
+#
+# Very complex queries can be performed using these substitution strings,
+# especially for virtual hosting.
+
+
+# Query to execute in order to fetch the password
+
+MYSQLGetPW SELECT password FROM ftp_users WHERE username="\L" AND login_enabled="y"
+
+
+# Query to execute in order to fetch the system user name or uid
+
+MYSQLGetUID SELECT uid FROM ftp_users WHERE username="\L" AND login_enabled="y"
+
+
+# Optional : default UID - if set this overrides MYSQLGetUID
+
+#MYSQLDefaultUID 1000
+
+
+# Query to execute in order to fetch the system user group or gid
+
+MYSQLGetGID SELECT gid FROM ftp_users WHERE username="\L" AND login_enabled="y"
+
+
+# Optional : default GID - if set this overrides MYSQLGetGID
+
+#MYSQLDefaultGID 1000
+
+
+# Query to execute in order to fetch the home directory
+
+MYSQLGetDir SELECT homedir FROM ftp_users WHERE username="\L" AND login_enabled="y"
+
+
+# Optional : query to get the maximal number of files
+# Pure-FTPd must have been compiled with virtual quotas support.
+
+# MySQLGetQTAFS SELECT QuotaFiles FROM users WHERE User='\L'
+
+
+# Optional : query to get the maximal disk usage (virtual quotas)
+# The number should be in Megabytes.
+# Pure-FTPd must have been compiled with virtual quotas support.
+
+MySQLGetQTASZ SELECT CASE WHEN panel_customers.diskspace = 0 THEN -1 WHEN panel_customers.diskspace <= -1 THEN 0 ELSE panel_customers.diskspace/1024 END AS QuotaSize FROM panel_customers, ftp_users WHERE username = "\L" AND panel_customers.loginname = SUBSTRING_INDEX('\L', 'ftp', 1)
+
+
+# Optional : ratios. The server has to be compiled with ratio support.
+
+# MySQLGetRatioUL SELECT ULRatio FROM users WHERE User='\L'
+# MySQLGetRatioDL SELECT DLRatio FROM users WHERE User='\L'
+
+
+# Optional : bandwidth throttling.
+# The server has to be compiled with throttling support.
+# Values are in KB/s .
+
+# MySQLGetBandwidthUL SELECT ULBandwidth FROM users WHERE User='\L'
+# MySQLGetBandwidthDL SELECT DLBandwidth FROM users WHERE User='\L'
+
+# Enable ~ expansion. NEVER ENABLE THIS BLINDLY UNLESS :
+# 1) You know what you are doing.
+# 2) Real and virtual users match.
+
+# MySQLForceTildeExpansion 1
+
+
+# If you're using a transactionnal storage engine, you can enable SQL
+# transactions to avoid races. Leave this commented if you are using the
+# traditional MyIsam engine.
+
+# MySQLTransactions On
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ //service[@type='smtp']/general/commands[@index=3]
+
+
+
+
+
+
+ *.log {
+ missingok
+ daily
+ rotate 7
+ compress
+ delaycompress
+ notifempty
+ create
+ sharedscripts
+ postrotate
+ > /dev/null 2>&1 || true
+ endscript
+}
+]]>
+
+
+
+
+
+
+
+
+ {{settings.system.mod_fcgid_ownvhost}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{settings.system.webserver}}
+
+
+
+
+
+ {{settings.system.webserver}}
+
+
+
+
+ {{settings.phpfpm.enabled_ownvhost}}
+
+ {{settings.phpfpm.vhost_httpuser}}
+
+
+
+
+
+ {{settings.system.webserver}}
+
+ {{settings.phpfpm.enabled_ownvhost}}
+
+
+
+
+ {{settings.system.webserver}}
+
+
+
+
+
+
+
+
+
+ bin/froxlor-cli /usr/local/bin/froxlor-cli]]>
+ bin/froxlor-cli froxlor:cron --run-task 99]]>
+
+
+
+
+
+
diff --git a/lib/formfields/admin/phpconfig/formfield.phpconfig_add.php b/lib/formfields/admin/phpconfig/formfield.phpconfig_add.php
index 157171f0d4..faa57dbaea 100644
--- a/lib/formfields/admin/phpconfig/formfield.phpconfig_add.php
+++ b/lib/formfields/admin/phpconfig/formfield.phpconfig_add.php
@@ -103,7 +103,7 @@
'maxlength' => 10,
'value' => '5s'
],
- 'phpfpm_pass_authorizationheader' => [
+ 'pass_authorizationheader' => [
'visible' => Settings::Get('system.webserver') == "apache2",
'label' => lng('admin.phpsettings.pass_authorizationheader'),
'type' => 'checkbox',
diff --git a/lib/formfields/admin/phpconfig/formfield.phpconfig_edit.php b/lib/formfields/admin/phpconfig/formfield.phpconfig_edit.php
index 8216c27bd0..746616a702 100644
--- a/lib/formfields/admin/phpconfig/formfield.phpconfig_edit.php
+++ b/lib/formfields/admin/phpconfig/formfield.phpconfig_edit.php
@@ -106,7 +106,7 @@
'maxlength' => 10,
'value' => $result['fpm_reqslow']
],
- 'phpfpm_pass_authorizationheader' => [
+ 'pass_authorizationheader' => [
'visible' => Settings::Get('system.webserver') == "apache2",
'label' => lng('admin.phpsettings.pass_authorizationheader'),
'type' => 'checkbox',
diff --git a/lib/init.php b/lib/init.php
index 9b1a67b8fc..c4cc5bdcb9 100644
--- a/lib/init.php
+++ b/lib/init.php
@@ -361,7 +361,7 @@
UI::twig()->addGlobal('csrf_token', $csrf_token);
// check if csrf token is valid
if (in_array($_SERVER['REQUEST_METHOD'], ['POST', 'PUT', 'PATCH', 'DELETE'])) {
- $current_token = $_POST['csrf_token'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null;
+ $current_token = Request::post('csrf_token', $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null);
if ($current_token != CurrentUser::getField('csrf_token')) {
http_response_code(403);
Response::dynamicError('CSRF validation failed');
@@ -369,7 +369,7 @@
}
// update cookie lifetime
$cookie_params = [
- 'expires' => time() + Settings::Get('session.sessiontimeout'),
+ 'expires' => time() + min(Settings::Get('session.sessiontimeout'), 31536000),
'path' => '/',
'domain' => UI::getCookieHost(),
'secure' => UI::requestIsHttps(),
diff --git a/lib/navigation/00.froxlor.main.php b/lib/navigation/00.froxlor.main.php
index 08b635839b..5e7d3230fb 100644
--- a/lib/navigation/00.froxlor.main.php
+++ b/lib/navigation/00.froxlor.main.php
@@ -161,13 +161,13 @@
'show_element' => (!Settings::IsInList('panel.customer_hide_options', 'misc.documentation')),
'elements' => [
[
- 'url' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/',
+ 'url' => \Froxlor\Froxlor::getDocsUrl() . 'user-guide/',
'label' => lng('admin.userguide'),
'new_window' => true,
'is_external' => true,
],
[
- 'url' => \Froxlor\Froxlor::DOCS_URL . 'api-guide/',
+ 'url' => \Froxlor\Froxlor::getDocsUrl() . 'api-guide/',
'label' => lng('admin.apiguide'),
'new_window' => true,
'show_element' => Settings::Get('api.enabled') == 1 && CurrentUser::getField('api_allowed') == 1,
@@ -348,13 +348,13 @@
'icon' => 'fa-solid fa-circle-info',
'elements' => [
[
- 'url' => \Froxlor\Froxlor::DOCS_URL . 'admin-guide/',
+ 'url' => \Froxlor\Froxlor::getDocsUrl() . 'admin-guide/',
'label' => lng('admin.adminguide'),
'new_window' => true,
'is_external' => true,
],
[
- 'url' => \Froxlor\Froxlor::DOCS_URL . 'api-guide/',
+ 'url' => \Froxlor\Froxlor::getDocsUrl() . 'api-guide/',
'label' => lng('admin.apiguide'),
'new_window' => true,
'show_element' => Settings::Get('api.enabled') == 1,
diff --git a/lng/de.lng.php b/lng/de.lng.php
index f1dadf7cea..b2c74158e3 100644
--- a/lng/de.lng.php
+++ b/lng/de.lng.php
@@ -1283,7 +1283,7 @@
'question' => [
'question' => 'Sicherheitsabfrage',
'admin_customer_reallydelete' => 'Wollen Sie den Kunden "%s" wirklich löschen?
ACHTUNG! Alle Daten gehen unwiderruflich verloren! Nach dem Vorgang müssen die Daten manuell aus dem Dateisystem entfernt werden.',
- 'admin_domain_reallydelete' => 'Wollen Sie die Domain "%s" wirklich löschen?',
+ 'admin_domain_reallydelete' => 'Wollen Sie die Domain "%s" wirklich löschen?
ACHTUNG: Alle Subdomains, FTP-Konten und E-Mail Adressen/Konten, welche mit dieser Domain verbunden sind, werden gelöscht!',
'admin_domain_reallydisablesecuritysetting' => 'Wollen Sie die wichtige Sicherheitseinstellung \'OpenBasedir\' wirklich deaktivieren?',
'admin_admin_reallydelete' => 'Wollen Sie den Admin "%s" wirklich löschen?
Alle Kunden und Domains dieses Admins werden Ihnen zugeteilt.',
'admin_template_reallydelete' => 'Wollen Sie die Vorlage "%s" wirklich löschen?',
@@ -1830,6 +1830,7 @@
],
'passwordcryptfunc' => [
'title' => 'Wählen Sie die zu verwendende Passwort-Verschlüsselungsmethode',
+ 'description' => 'Wählen Sie, welche Methode zur Verschlüsselung von Kennwörtern verwendet werden soll. Wenn Sie diese Einstellung ändern, werden nur neue Kennwörter mit der neuen Methode verschlüsselt. Bestehende Passwörter werden nicht geändert.'
],
'systemdefault' => 'Systemstandard',
'panel_allow_theme_change_admin' => 'Erlaube Admins das Theme zu wechseln',
diff --git a/lng/en.lng.php b/lng/en.lng.php
index 92671caafa..ade416d177 100644
--- a/lng/en.lng.php
+++ b/lng/en.lng.php
@@ -1398,7 +1398,7 @@
'question' => [
'question' => 'Security question',
'admin_customer_reallydelete' => 'Do you really want to delete the customer %s? This cannot be undone!',
- 'admin_domain_reallydelete' => 'Do you really want to delete the domain %s?',
+ 'admin_domain_reallydelete' => 'Do you really want to delete the domain %s?
NOTE: All subdomains, ftp-accounts and email-addresses/accounts connected to this domain will be removed!',
'admin_domain_reallydisablesecuritysetting' => 'Do you really want to disable this security setting OpenBasedir?',
'admin_admin_reallydelete' => 'Do you really want to delete the admin %s? Every customer and domain will be reassigned to your account.',
'admin_template_reallydelete' => 'Do you really want to delete the template \'%s\'?',
@@ -1952,6 +1952,7 @@
],
'passwordcryptfunc' => [
'title' => 'Choose which password-crypt method is to be used',
+ 'description' => 'Choose which password-crypt method is to be used. If you change this setting, only new passwords will be encrypted with the new method. Existing passwords will not be changed.',
],
'systemdefault' => 'System default',
'panel_allow_theme_change_admin' => 'Allow admins to change the theme',
diff --git a/package-lock.json b/package-lock.json
index 5c81ed2612..b60030b662 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,7 +19,7 @@
"postcss": "^8.1.14",
"resolve-url-loader": "^5.0.0",
"sass": "^1.69.3",
- "vite": "^4.5.2",
+ "vite": "^4.5.3",
"vue": "^3.2.37"
},
"engines": {
@@ -776,9 +776,9 @@
}
},
"node_modules/follow-redirects": {
- "version": "1.15.4",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
- "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
+ "version": "1.15.6",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+ "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"dev": true,
"funding": [
{
@@ -1156,9 +1156,9 @@
}
},
"node_modules/vite": {
- "version": "4.5.2",
- "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz",
- "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==",
+ "version": "4.5.3",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
+ "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
"dev": true,
"dependencies": {
"esbuild": "^0.18.10",
diff --git a/package.json b/package.json
index 17928d7c10..401e4a1078 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"postcss": "^8.1.14",
"resolve-url-loader": "^5.0.0",
"sass": "^1.69.3",
- "vite": "^4.5.2",
+ "vite": "^4.5.3",
"vue": "^3.2.37"
},
"engines": {
diff --git a/ssl_certificates.php b/ssl_certificates.php
index bd917e68db..3b73f3de7a 100644
--- a/ssl_certificates.php
+++ b/ssl_certificates.php
@@ -55,7 +55,7 @@
'section' => 'domains',
'page' => $page
]);
-} elseif (isset($_POST['send']) && $_POST['send'] == 'send' && $action == 'deletesure' && $id > 0) {
+} elseif (Request::post('send') == 'send' && $action == 'deletesure' && $id > 0) {
try {
$json_result = Certificates::getLocal($userinfo, [
'id' => $id
diff --git a/ssl_editor.php b/ssl_editor.php
index d4b7bab355..b0d1c77051 100644
--- a/ssl_editor.php
+++ b/ssl_editor.php
@@ -33,6 +33,7 @@
use Froxlor\Database\Database;
use Froxlor\PhpHelper;
use Froxlor\UI\Panel\UI;
+use Froxlor\UI\Request;
use Froxlor\UI\Response;
// This file is being included in admin_domains and customer_domains
@@ -49,13 +50,13 @@
}
$result_domain = json_decode($json_result, true)['data'];
- if (isset($_POST['send']) && $_POST['send'] == 'send') {
- $do_insert = isset($_POST['do_insert']) && ((($_POST['do_insert'] == 1) ? true : false));
+ if (Request::post('send') == 'send') {
+ $do_insert = Request::post('do_insert', 0) == 1;
try {
if ($do_insert) {
- Certificates::getLocal($userinfo, $_POST)->add();
+ Certificates::getLocal($userinfo, Request::postAll())->add();
} else {
- Certificates::getLocal($userinfo, $_POST)->update();
+ Certificates::getLocal($userinfo, Request::postAll())->update();
}
} catch (Exception $e) {
Response::dynamicError($e->getMessage());
diff --git a/templates/Froxlor/assets/js/jquery/apikeys.js b/templates/Froxlor/assets/js/jquery/apikeys.js
index c5203cd3c1..641c17e0f6 100644
--- a/templates/Froxlor/assets/js/jquery/apikeys.js
+++ b/templates/Froxlor/assets/js/jquery/apikeys.js
@@ -1,6 +1,6 @@
export default function () {
$(function () {
- var timer, delay = 500;
+ var timer, delay = 650;
$('div[data-action="apikeys"] #allowed_from').on('keyup change', function () {
var _this = $(this);
clearTimeout(timer);
@@ -54,7 +54,7 @@ export default function () {
} else {
_this.removeClass('is-invalid');
_this.addClass('is-valid');
- _this.val(data.valid_until);
+ //_this.val(data.valid_until);
}
},
error: function (request, status, error) {
diff --git a/templates/Froxlor/assets/js/jquery/customer.js b/templates/Froxlor/assets/js/jquery/customer.js
index 73ca39dc1b..2be1e1a6d5 100644
--- a/templates/Froxlor/assets/js/jquery/customer.js
+++ b/templates/Froxlor/assets/js/jquery/customer.js
@@ -31,7 +31,7 @@ export default function () {
planid: pid
},
dataType: "json",
- beforeSend: function(request) {
+ beforeSend: function (request) {
request.setRequestHeader('X-CSRF-TOKEN', document.querySelector('meta[name="csrf-token"]').getAttribute('content'));
},
success: function (json) {
diff --git a/templates/Froxlor/assets/js/jquery/domains.js b/templates/Froxlor/assets/js/jquery/domains.js
index ede1f1f55d..9e3766ec09 100644
--- a/templates/Froxlor/assets/js/jquery/domains.js
+++ b/templates/Froxlor/assets/js/jquery/domains.js
@@ -13,6 +13,9 @@ export default function () {
customerid: cid
},
dataType: "json",
+ beforeSend: function (request) {
+ request.setRequestHeader('X-CSRF-TOKEN', document.querySelector('meta[name="csrf-token"]').getAttribute('content'));
+ },
success: function (json) {
if (json.length > 0) {
$('#phpsettingid option').each(function () {
@@ -45,6 +48,10 @@ export default function () {
id: $('input[name=id]').val(), newval: +$('#speciallogfile').is(':checked')
},
dataType: "json",
+ async: false,
+ beforeSend: function (request) {
+ request.setRequestHeader('X-CSRF-TOKEN', document.querySelector('meta[name="csrf-token"]').getAttribute('content'));
+ },
success: function (json) {
if (json.changed) {
$('#speciallogfile').addClass('is-invalid');
@@ -66,7 +73,6 @@ export default function () {
$('#section_b').hide();
$('#section_bssl').hide();
$('#section_c').hide();
- $('#section_d').hide();
}
/**
@@ -78,13 +84,11 @@ export default function () {
$('#section_b').hide();
$('#section_bssl').hide();
$('#section_c').hide();
- $('#section_d').hide();
} else {
// show sections
$('#section_b').show();
$('#section_bssl').show();
$('#section_c').show();
- $('#section_d').show();
}
})
diff --git a/templates/Froxlor/assets/js/jquery/global.js b/templates/Froxlor/assets/js/jquery/global.js
index 067c4dffc6..5127dace48 100644
--- a/templates/Froxlor/assets/js/jquery/global.js
+++ b/templates/Froxlor/assets/js/jquery/global.js
@@ -12,9 +12,14 @@ export default function () {
new bootstrap.Popover($(this));
})
+ if (!window.isSecureContext) {
+ // hide all copyClipboard buttons as this only works in a secure context
+ $('.copyClipboard').hide();
+ }
+
$('.copyClipboard').on('click', function (e) {
e.preventDefault();
- const source_element = $(this).data('clipboard-source').text();
+ const source_element = $(this).data('clipboard-source');
navigator.clipboard.writeText($('#' + source_element).text().trim());
})
diff --git a/templates/Froxlor/assets/js/jquery/ipsandports.js b/templates/Froxlor/assets/js/jquery/ipsandports.js
index a14de4a11d..bc9e0c2814 100644
--- a/templates/Froxlor/assets/js/jquery/ipsandports.js
+++ b/templates/Froxlor/assets/js/jquery/ipsandports.js
@@ -15,6 +15,9 @@ export default function () {
ip: ipval
},
dataType: "json",
+ beforeSend: function (request) {
+ request.setRequestHeader('X-CSRF-TOKEN', document.querySelector('meta[name="csrf-token"]').getAttribute('content'));
+ },
success: function (json) {
if (json != 0) {
$('#ip').addClass('is-invalid');
diff --git a/templates/Froxlor/assets/js/jquery/updatecheck.js b/templates/Froxlor/assets/js/jquery/updatecheck.js
index dcc5ef4096..45cfdbe28b 100644
--- a/templates/Froxlor/assets/js/jquery/updatecheck.js
+++ b/templates/Froxlor/assets/js/jquery/updatecheck.js
@@ -4,12 +4,24 @@ export default function () {
* updatecheck
*/
if (document.getElementById('updatecheck')) {
+ runCheck();
+ }
+
+ function runCheck(force = 0)
+ {
$.ajax({
- url: "lib/ajax.php?action=updatecheck&theme=" + window.$theme,
+ url: "lib/ajax.php?action=updatecheck&theme=" + window.$theme + "&force=" + force,
type: "GET",
success: function (data) {
$("#updatecheck").html(data);
- new bootstrap.Popover(document.getElementById('ucheck'));
+ const po = new bootstrap.Popover(document.getElementById('ucheck'));
+ const myPopoverTrigger = document.getElementById('ucheck')
+ myPopoverTrigger.addEventListener('shown.bs.popover', () => {
+ $('#forceUpdateCheck').on('click', function () {
+ runCheck(1);
+ po.hide();
+ });
+ })
},
error: function (request, status, error) {
console.log(request, status, error)
diff --git a/templates/Froxlor/assets/scss/_variables.scss b/templates/Froxlor/assets/scss/_variables.scss
index 8e1bef65e2..08a97dbf2d 100644
--- a/templates/Froxlor/assets/scss/_variables.scss
+++ b/templates/Froxlor/assets/scss/_variables.scss
@@ -86,3 +86,6 @@ $heading-border-color-dark: rgba(0,0,0,0.15);
// Search
$search-bg: $navbar-bg;
+
+// Popover size
+$popover-max-width: 320px;
diff --git a/templates/Froxlor/misc/version_popover.html.twig b/templates/Froxlor/misc/version_popover.html.twig
index 554bc0ebfd..ee1642cebc 100644
--- a/templates/Froxlor/misc/version_popover.html.twig
+++ b/templates/Froxlor/misc/version_popover.html.twig
@@ -26,4 +26,7 @@
{{ call_static('\\Froxlor\\Froxlor', 'getInstallDir') }}bin/froxlor-cli froxlor:update
{% endif %}
{% endif %}
+
+
+
{% endmacro %}
diff --git a/templates/Froxlor/table/macros.html.twig b/templates/Froxlor/table/macros.html.twig
index c006f4bd7c..3a8e49106b 100644
--- a/templates/Froxlor/table/macros.html.twig
+++ b/templates/Froxlor/table/macros.html.twig
@@ -52,25 +52,8 @@
{{ data.text }}
{% endif %}
{% if data.href is defined %}a{% else %}span{% endif %}>
- {% if data.modal is defined and data.modal is iterable %}
-
-
-
-
-
- {{ data.modal.body|raw }}
-
-
-
-
-
- {% endif %}
{% endapply %}
+ {# the modal-markup if any will be generated using actions_modal()-macro after the table itself #}
{% endmacro %}
{% macro domainWithSan(data) %}
@@ -90,3 +73,30 @@
{% endif %}
{% endfor %}
{% endmacro %}
+
+{% macro actions_modal(data) %}
+ {% for action in data %}
+ {% if action.visible is not defined or action.visible is defined and action.visible %}
+ {% apply spaceless %}
+ {% if action.modal is defined and action.modal is iterable %}
+
+
+
+
+
+ {{ action.modal.body|raw }}
+
+
+
+
+
+ {% endif %}
+ {% endapply %}
+ {% endif %}
+ {% endfor %}
+{% endmacro %}
diff --git a/templates/Froxlor/table/table.html.twig b/templates/Froxlor/table/table.html.twig
index 6b8ac96b12..3c4384cb58 100644
--- a/templates/Froxlor/table/table.html.twig
+++ b/templates/Froxlor/table/table.html.twig
@@ -64,6 +64,14 @@
{{ pagination.paging(listing.pagination) }}
{% endif %}
+ {# handle potential modal-html if defined by actions #}
+ {% for tr in listing.table.tr %}
+ {% for td in tr.td %}
+ {% if td.data is iterable and td.data.macro == 'actions' %}
+ {{ macros.actions_modal(td.data.data) }}
+ {% endif %}
+ {% endfor %}
+ {% endfor %}
{% endif %}