Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3b0332d13 | ||
|
|
4b1846883d | ||
|
|
778fd3ba65 | ||
|
|
00456a35e5 | ||
|
|
5958f0516b | ||
|
|
166ffedf04 | ||
|
|
36dfee1263 | ||
|
|
ec0026ecfd | ||
|
|
a721bb3f21 | ||
|
|
83de3dd719 |
@@ -60,7 +60,9 @@ if ($userinfo['change_serversettings'] == '1') {
|
|||||||
|
|
||||||
if (!empty($distribution)) {
|
if (!empty($distribution)) {
|
||||||
if (!file_exists($config_dir . '/' . $distribution . ".xml")) {
|
if (!file_exists($config_dir . '/' . $distribution . ".xml")) {
|
||||||
Response::dynamicError("Unknown distribution");
|
// unknown distribution -> redirect to select a valid distribution for config-templates
|
||||||
|
Settings::Set('system.distribution', '');
|
||||||
|
Response::redirectTo('admin_configfiles.php', ['reselect' => 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update setting if different
|
// update setting if different
|
||||||
|
|||||||
@@ -115,8 +115,8 @@ if ($page == 'overview') {
|
|||||||
$userinfo['traffic_bytes_used'] = $userinfo['traffic_used'] * 1024;
|
$userinfo['traffic_bytes_used'] = $userinfo['traffic_used'] * 1024;
|
||||||
|
|
||||||
if (Settings::Get('system.mail_quota_enabled')) {
|
if (Settings::Get('system.mail_quota_enabled')) {
|
||||||
$userinfo['email_quota_bytes'] = ($userinfo['email_quota'] > -1) ? $userinfo['email_quota'] * 1024 : -1;
|
$userinfo['email_quota_bytes'] = ($userinfo['email_quota'] > -1) ? $userinfo['email_quota'] * 1024 * 1024 : -1;
|
||||||
$userinfo['email_quota_bytes_used'] = $userinfo['email_quota_used'] * 1024;
|
$userinfo['email_quota_bytes_used'] = $userinfo['email_quota_used'] * 1024 * 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($usages) {
|
if ($usages) {
|
||||||
|
|||||||
17
index.php
17
index.php
@@ -74,27 +74,26 @@ if ($action == '2fa_entercode') {
|
|||||||
$code = isset($_POST['2fa_code']) ? $_POST['2fa_code'] : null;
|
$code = isset($_POST['2fa_code']) ? $_POST['2fa_code'] : null;
|
||||||
// verify entered code
|
// verify entered code
|
||||||
$tfa = new FroxlorTwoFactorAuth('Froxlor ' . Settings::Get('system.hostname'));
|
$tfa = new FroxlorTwoFactorAuth('Froxlor ' . Settings::Get('system.hostname'));
|
||||||
$result = ($_SESSION['secret_2fa'] == 'email' ? true : $tfa->verifyCode($_SESSION['secret_2fa'], $code, 3));
|
|
||||||
// get user-data
|
// get user-data
|
||||||
$table = $_SESSION['uidtable_2fa'];
|
$table = $_SESSION['uidtable_2fa'];
|
||||||
$field = $_SESSION['uidfield_2fa'];
|
$field = $_SESSION['uidfield_2fa'];
|
||||||
$uid = $_SESSION['uid_2fa'];
|
$uid = $_SESSION['uid_2fa'];
|
||||||
$isadmin = $_SESSION['unfo_2fa'];
|
$isadmin = $_SESSION['unfo_2fa'];
|
||||||
|
if ($_SESSION['secret_2fa'] == 'email') {
|
||||||
|
// verify code set to user's data_2fa field
|
||||||
|
$sel_stmt = Database::prepare("SELECT `data_2fa` FROM " . $table . " WHERE `" . $field . "` = :uid");
|
||||||
|
$userinfo_code = Database::pexecute_first($sel_stmt, ['uid' => $uid]);
|
||||||
|
$result = $tfa->verifyCode($userinfo_code['data_2fa'], $code);
|
||||||
|
} else {
|
||||||
|
$result = $tfa->verifyCode($_SESSION['secret_2fa'], $code, 3);
|
||||||
|
}
|
||||||
// either the code is valid when using authenticator-app, or we will select userdata by id and entered code
|
// either the code is valid when using authenticator-app, or we will select userdata by id and entered code
|
||||||
// which is temporarily stored for the customer when using email-2fa
|
// which is temporarily stored for the customer when using email-2fa
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$sel_param = [
|
$sel_param = [
|
||||||
'uid' => $uid
|
'uid' => $uid
|
||||||
];
|
];
|
||||||
if ($_SESSION['secret_2fa'] == 'email') {
|
|
||||||
// verify code by selecting user by id and the temp. stored code,
|
|
||||||
// so only if it's the correct code, we get the user-data
|
|
||||||
$sel_stmt = Database::prepare("SELECT * FROM " . $table . " WHERE `" . $field . "` = :uid AND `data_2fa` = :code");
|
|
||||||
$sel_param['code'] = $code;
|
|
||||||
} else {
|
|
||||||
// Authenticator-verification has already happened at this point, so just get the user-data
|
|
||||||
$sel_stmt = Database::prepare("SELECT * FROM " . $table . " WHERE `" . $field . "` = :uid");
|
$sel_stmt = Database::prepare("SELECT * FROM " . $table . " WHERE `" . $field . "` = :uid");
|
||||||
}
|
|
||||||
$userinfo = Database::pexecute_first($sel_stmt, $sel_param);
|
$userinfo = Database::pexecute_first($sel_stmt, $sel_param);
|
||||||
// whoops, no (valid) user? Start again
|
// whoops, no (valid) user? Start again
|
||||||
if (empty($userinfo)) {
|
if (empty($userinfo)) {
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ CREATE TABLE `panel_admins` (
|
|||||||
`api_allowed` tinyint(1) NOT NULL default '1',
|
`api_allowed` tinyint(1) NOT NULL default '1',
|
||||||
PRIMARY KEY (`adminid`),
|
PRIMARY KEY (`adminid`),
|
||||||
UNIQUE KEY `loginname` (`loginname`)
|
UNIQUE KEY `loginname` (`loginname`)
|
||||||
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
|
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `panel_customers`;
|
DROP TABLE IF EXISTS `panel_customers`;
|
||||||
@@ -299,7 +299,7 @@ CREATE TABLE `panel_domains` (
|
|||||||
KEY `customerid` (`customerid`),
|
KEY `customerid` (`customerid`),
|
||||||
KEY `parentdomain` (`parentdomainid`),
|
KEY `parentdomain` (`parentdomainid`),
|
||||||
KEY `domain` (`domain`)
|
KEY `domain` (`domain`)
|
||||||
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
|
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `panel_ipsandports`;
|
DROP TABLE IF EXISTS `panel_ipsandports`;
|
||||||
@@ -678,7 +678,7 @@ opcache.validate_timestamps'),
|
|||||||
('system', 'distribution', ''),
|
('system', 'distribution', ''),
|
||||||
('system', 'update_channel', 'stable'),
|
('system', 'update_channel', 'stable'),
|
||||||
('system', 'updatecheck_data', ''),
|
('system', 'updatecheck_data', ''),
|
||||||
('system', 'update_notify_last', '2.1.1'),
|
('system', 'update_notify_last', ''),
|
||||||
('system', 'traffictool', 'goaccess'),
|
('system', 'traffictool', 'goaccess'),
|
||||||
('system', 'req_limit_per_interval', 60),
|
('system', 'req_limit_per_interval', 60),
|
||||||
('system', 'req_limit_interval', 60),
|
('system', 'req_limit_interval', 60),
|
||||||
@@ -726,8 +726,8 @@ opcache.validate_timestamps'),
|
|||||||
('panel', 'logo_overridecustom', '0'),
|
('panel', 'logo_overridecustom', '0'),
|
||||||
('panel', 'settings_mode', '0'),
|
('panel', 'settings_mode', '0'),
|
||||||
('panel', 'menu_collapsed', '1'),
|
('panel', 'menu_collapsed', '1'),
|
||||||
('panel', 'version', '2.1.1'),
|
('panel', 'version', '2.1.2'),
|
||||||
('panel', 'db_version', '202312050');
|
('panel', 'db_version', '202312120');
|
||||||
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `panel_tasks`;
|
DROP TABLE IF EXISTS `panel_tasks`;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ if (!defined('_CRON_UPDATE')) {
|
|||||||
|
|
||||||
if (Froxlor::isFroxlorVersion('2.0.24')) {
|
if (Froxlor::isFroxlorVersion('2.0.24')) {
|
||||||
Update::showUpdateStep("Cleaning domains table");
|
Update::showUpdateStep("Cleaning domains table");
|
||||||
|
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ROW_FORMAT=DYNAMIC;");
|
||||||
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` DROP COLUMN `ismainbutsubto`;");
|
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` DROP COLUMN `ismainbutsubto`;");
|
||||||
Update::lastStepStatus(0);
|
Update::lastStepStatus(0);
|
||||||
|
|
||||||
@@ -213,3 +214,58 @@ if (Froxlor::isFroxlorVersion('2.1.0')) {
|
|||||||
Update::showUpdateStep("Updating from 2.1.0 to 2.1.1", false);
|
Update::showUpdateStep("Updating from 2.1.0 to 2.1.1", false);
|
||||||
Froxlor::updateToVersion('2.1.1');
|
Froxlor::updateToVersion('2.1.1');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Froxlor::isDatabaseVersion('202312050')) {
|
||||||
|
Update::showUpdateStep("Cleaning up old files");
|
||||||
|
$to_clean = array(
|
||||||
|
"lib/configfiles/centos7.xml",
|
||||||
|
"lib/configfiles/centos8.xml",
|
||||||
|
"lib/configfiles/stretch.xml",
|
||||||
|
"lib/configfiles/xenial.xml",
|
||||||
|
"lib/configfiles/buster.xml",
|
||||||
|
"lib/configfiles/bionic.xml",
|
||||||
|
);
|
||||||
|
$disabled = explode(',', ini_get('disable_functions'));
|
||||||
|
$exec_allowed = !in_array('exec', $disabled);
|
||||||
|
$del_list = "";
|
||||||
|
foreach ($to_clean as $filedir) {
|
||||||
|
$complete_filedir = Froxlor::getInstallDir() . $filedir;
|
||||||
|
if (file_exists($complete_filedir)) {
|
||||||
|
if ($exec_allowed) {
|
||||||
|
FileDir::safe_exec("rm -rf " . escapeshellarg($complete_filedir));
|
||||||
|
} else {
|
||||||
|
$del_list .= "rm -rf " . escapeshellarg($complete_filedir) . PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($exec_allowed) {
|
||||||
|
Update::lastStepStatus(0);
|
||||||
|
} else {
|
||||||
|
if (empty($del_list)) {
|
||||||
|
// none of the files existed
|
||||||
|
Update::lastStepStatus(0);
|
||||||
|
} else {
|
||||||
|
Update::lastStepStatus(
|
||||||
|
1,
|
||||||
|
'manual commands needed',
|
||||||
|
'Please run the following commands manually:<br><pre>' . $del_list . '</pre>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Froxlor::updateToDbVersion('202312100');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Froxlor::isDatabaseVersion('202312100')) {
|
||||||
|
|
||||||
|
Update::showUpdateStep("Adjusting table row format of larger tables");
|
||||||
|
Database::query("ALTER TABLE `" . TABLE_PANEL_ADMINS . "` ROW_FORMAT=DYNAMIC;");
|
||||||
|
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ROW_FORMAT=DYNAMIC;");
|
||||||
|
Update::lastStepStatus(0);
|
||||||
|
|
||||||
|
Froxlor::updateToDbVersion('202312120');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Froxlor::isFroxlorVersion('2.1.1')) {
|
||||||
|
Update::showUpdateStep("Updating from 2.1.1 to 2.1.2", false);
|
||||||
|
Froxlor::updateToVersion('2.1.2');
|
||||||
|
}
|
||||||
|
|||||||
@@ -1053,7 +1053,7 @@ class Customers extends ApiCommand implements ResourceEntity
|
|||||||
$email = $this->getParam('email', true, $idna_convert->decode($result['email']));
|
$email = $this->getParam('email', true, $idna_convert->decode($result['email']));
|
||||||
$name = $this->getParam('name', true, $result['name']);
|
$name = $this->getParam('name', true, $result['name']);
|
||||||
$firstname = $this->getParam('firstname', true, $result['firstname']);
|
$firstname = $this->getParam('firstname', true, $result['firstname']);
|
||||||
$company_required = empty($result['company']) && ((!empty($name) && empty($firstname)) || (empty($name) && !empty($firstname)) || (empty($name) && empty($firstname)));
|
$company_required = (!empty($name) && empty($firstname)) || (empty($name) && !empty($firstname)) || (empty($name) && empty($firstname));
|
||||||
$company = $this->getParam('company', !$company_required, $result['company']);
|
$company = $this->getParam('company', !$company_required, $result['company']);
|
||||||
$street = $this->getParam('street', true, $result['street']);
|
$street = $this->getParam('street', true, $result['street']);
|
||||||
$zipcode = $this->getParam('zipcode', true, $result['zipcode']);
|
$zipcode = $this->getParam('zipcode', true, $result['zipcode']);
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ abstract class DnsBase
|
|||||||
'zonefile' => '',
|
'zonefile' => '',
|
||||||
'froxlorhost' => '1'
|
'froxlorhost' => '1'
|
||||||
];
|
];
|
||||||
$domains['none'] = $hostname_arr;
|
$domains[0] = $hostname_arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($domains)) {
|
if (empty($domains)) {
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ final class Froxlor
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Main version variable
|
// Main version variable
|
||||||
const VERSION = '2.1.1';
|
const VERSION = '2.1.2';
|
||||||
|
|
||||||
// Database version (YYYYMMDDC where C is a daily counter)
|
// Database version (YYYYMMDDC where C is a daily counter)
|
||||||
const DBVERSION = '202312050';
|
const DBVERSION = '202312120';
|
||||||
|
|
||||||
// Distribution branding-tag (used for Debian etc.)
|
// Distribution branding-tag (used for Debian etc.)
|
||||||
const BRANDING = '';
|
const BRANDING = '';
|
||||||
|
|||||||
@@ -220,8 +220,11 @@ class PhpHelper
|
|||||||
if (is_dir($data_dirname)) {
|
if (is_dir($data_dirname)) {
|
||||||
$data_dirhandle = opendir($data_dirname);
|
$data_dirhandle = opendir($data_dirname);
|
||||||
while (false !== ($data_filename = readdir($data_dirhandle))) {
|
while (false !== ($data_filename = readdir($data_dirhandle))) {
|
||||||
if ($data_filename != '.' && $data_filename != '..' && $data_filename != '' && substr($data_filename,
|
if ($data_filename != '.'
|
||||||
-4) == '.php') {
|
&& $data_filename != '..'
|
||||||
|
&& $data_filename != ''
|
||||||
|
&& substr($data_filename, -4) == '.php'
|
||||||
|
) {
|
||||||
$data_files[] = $data_dirname . $data_filename;
|
$data_files[] = $data_dirname . $data_filename;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -458,6 +461,10 @@ class PhpHelper
|
|||||||
'directory_password',
|
'directory_password',
|
||||||
'ftp_password',
|
'ftp_password',
|
||||||
'mysql_password',
|
'mysql_password',
|
||||||
|
'mysql_root_pass',
|
||||||
|
'mysql_unprivileged_pass',
|
||||||
|
'admin_pass',
|
||||||
|
'admin_pass_confirm',
|
||||||
];
|
];
|
||||||
if (!empty($global)) {
|
if (!empty($global)) {
|
||||||
$tmp = $global;
|
$tmp = $global;
|
||||||
@@ -557,4 +564,17 @@ class PhpHelper
|
|||||||
}
|
}
|
||||||
return $tab . $str;
|
return $tab . $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function array_merge_recursive_distinct(array &$array1, array &$array2)
|
||||||
|
{
|
||||||
|
$merged = $array1;
|
||||||
|
foreach ($array2 as $key => &$value) {
|
||||||
|
if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
|
||||||
|
$merged[$key] = self::array_merge_recursive_distinct($merged[$key], $value);
|
||||||
|
} else {
|
||||||
|
$merged[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $merged;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ if (is_array($_themeoptions) && (!array_key_exists('variants', $_themeoptions) |
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('global', $_themeoptions)) {
|
if (array_key_exists('global', $_themeoptions)) {
|
||||||
$_themeoptions['variants'][$themevariant] = array_merge_recursive($_themeoptions['variants'][$themevariant], $_themeoptions['global']);
|
$_themeoptions['variants'][$themevariant] = PhpHelper::array_merge_recursive_distinct($_themeoptions['global'], $_themeoptions['variants'][$themevariant]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for custom header-graphic
|
// check for custom header-graphic
|
||||||
|
|||||||
@@ -8,18 +8,18 @@ export default function () {
|
|||||||
rules: {
|
rules: {
|
||||||
'name': {
|
'name': {
|
||||||
required: function () {
|
required: function () {
|
||||||
return $('#company').val().length === 0 || $('#firstname').val().length > 0;
|
return $('#company').val().trim().length === 0 || $('#firstname').val().trim().length > 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'firstname': {
|
'firstname': {
|
||||||
required: function () {
|
required: function () {
|
||||||
return $('#company').val().length === 0 || $('#name').val().length > 0;
|
return $('#company').val().trim().length === 0 || $('#name').val().trim().length > 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'company': {
|
'company': {
|
||||||
required: function () {
|
required: function () {
|
||||||
return $('#name').val().length === 0
|
return $('#name').val().trim().length === 0
|
||||||
&& $('#firstname').val().length === 0;
|
&& $('#firstname').val().trim().length === 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -184,7 +184,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% set field = field|merge({'type':'file'}) %}
|
{% set field = field|merge({'type':'file'})|merge({'value':''}) %}
|
||||||
{{ _self.input(id, field) }}
|
{{ _self.input(id, field) }}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user