This commit is contained in:
Daniel
2021-07-13 10:31:24 +08:00
28 changed files with 770 additions and 517 deletions

1
.gitignore vendored
View File

@@ -12,6 +12,7 @@ logs/*
.well-known .well-known
.idea .idea
*.iml *.iml
img/
!templates/Froxlor/ !templates/Froxlor/
!templates/Sparkle/ !templates/Sparkle/

View File

@@ -296,6 +296,24 @@ return array(
'default' => '', 'default' => '',
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),
'panel_logo_image_header' => array(
'label' => $lng['serversettings']['logo_image_header'],
'settinggroup' => 'panel',
'varname' => 'logo_image_header',
'type' => 'image',
'image_name' => 'logo_header',
'default' => '',
'save_method' => 'storeSettingImage'
),
'panel_logo_image_login' => array(
'label' => $lng['serversettings']['logo_image_login'],
'settinggroup' => 'panel',
'varname' => 'logo_image_login',
'type' => 'image',
'image_name' => 'logo_login',
'default' => '',
'save_method' => 'storeSettingImage'
),
) )
) )
) )

View File

@@ -142,6 +142,9 @@ return array(
'default' => '/etc/apache2/conf-enabled/acme.conf', 'default' => '/etc/apache2/conf-enabled/acme.conf',
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),
/**
* currently the only option anyway
*
'system_leapiversion' => array( 'system_leapiversion' => array(
'label' => $lng['serversettings']['leapiversion'], 'label' => $lng['serversettings']['leapiversion'],
'settinggroup' => 'system', 'settinggroup' => 'system',
@@ -154,16 +157,18 @@ return array(
), ),
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),
*/
'system_letsencryptca' => array( 'system_letsencryptca' => array(
'label' => $lng['serversettings']['letsencryptca'], 'label' => $lng['serversettings']['letsencryptca'],
'settinggroup' => 'system', 'settinggroup' => 'system',
'varname' => 'letsencryptca', 'varname' => 'letsencryptca',
'type' => 'option', 'type' => 'option',
'default' => 'production', 'default' => 'letsencrypt',
'option_mode' => 'one', 'option_mode' => 'one',
'option_options' => array( 'option_options' => array(
'testing' => 'https://acme-staging-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org (Test)', 'letsencrypt_test' => 'Let\'s Encrypt (Test / Staging)',
'production' => 'https://acme-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org (Live)' 'letsencrypt' => 'Let\'s Encrypt (Live)',
'zerossl' => 'ZeroSSL (Live)'
), ),
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),

View File

@@ -43,6 +43,7 @@
"ext-curl": "*", "ext-curl": "*",
"ext-json": "*", "ext-json": "*",
"ext-openssl": "*", "ext-openssl": "*",
"ext-fileinfo": "*",
"phpmailer/phpmailer": "~6.0", "phpmailer/phpmailer": "~6.0",
"monolog/monolog": "^1.24", "monolog/monolog": "^1.24",
"robthree/twofactorauth": "^1.6", "robthree/twofactorauth": "^1.6",

14
composer.lock generated
View File

@@ -150,16 +150,16 @@
}, },
{ {
"name": "phpmailer/phpmailer", "name": "phpmailer/phpmailer",
"version": "v6.4.1", "version": "v6.5.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git", "url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "9256f12d8fb0cd0500f93b19e18c356906cbed3d" "reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/9256f12d8fb0cd0500f93b19e18c356906cbed3d", "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a5b5c43e50b7fba655f793ad27303cd74c57363c",
"reference": "9256f12d8fb0cd0500f93b19e18c356906cbed3d", "reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -214,7 +214,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP", "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": { "support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues", "issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.4.1" "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.0"
}, },
"funding": [ "funding": [
{ {
@@ -222,7 +222,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2021-04-29T12:25:04+00:00" "time": "2021-06-16T14:33:43+00:00"
}, },
{ {
"name": "psr/log", "name": "psr/log",
@@ -4133,5 +4133,5 @@
"php": ">=7.3", "php": ">=7.3",
"ext-pcntl": "*" "ext-pcntl": "*"
}, },
"plugin-api-version": "2.0.0" "plugin-api-version": "2.1.0"
} }

View File

@@ -628,7 +628,7 @@ opcache.interned_strings_buffer'),
('system', 'apacheitksupport', '0'), ('system', 'apacheitksupport', '0'),
('system', 'leprivatekey', 'unset'), ('system', 'leprivatekey', 'unset'),
('system', 'lepublickey', 'unset'), ('system', 'lepublickey', 'unset'),
('system', 'letsencryptca', 'production'), ('system', 'letsencryptca', 'letsencrypt'),
('system', 'letsencryptcountrycode', 'DE'), ('system', 'letsencryptcountrycode', 'DE'),
('system', 'letsencryptstate', 'Hessen'), ('system', 'letsencryptstate', 'Hessen'),
('system', 'letsencryptchallengepath', '/var/www/froxlor'), ('system', 'letsencryptchallengepath', '/var/www/froxlor'),
@@ -715,8 +715,10 @@ opcache.interned_strings_buffer'),
('panel', 'imprint_url', ''), ('panel', 'imprint_url', ''),
('panel', 'terms_url', ''), ('panel', 'terms_url', ''),
('panel', 'privacy_url', ''), ('panel', 'privacy_url', ''),
('panel', 'logo_image_header', ''),
('panel', 'logo_image_login', ''),
('panel', 'version', '0.10.26'), ('panel', 'version', '0.10.26'),
('panel', 'db_version', '202106160'); ('panel', 'db_version', '202107070');
DROP TABLE IF EXISTS `panel_tasks`; DROP TABLE IF EXISTS `panel_tasks`;

View File

@@ -784,7 +784,7 @@ class FroxlorInstall
} }
// language selection // language selection
$language_options = ''; $language_options = '';
foreach ($this->_languages as $language_name => $language_file) { foreach ($this->_languages as $language_file => $language_name) {
$language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $this->_activelng, true, true); $language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $this->_activelng, true, true);
} }
// get language-form-template // get language-form-template
@@ -867,19 +867,24 @@ class FroxlorInstall
} }
// show list of available distro's // show list of available distro's
$distributions_select_data = [];
$distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml'); $distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml');
foreach ($distros as $_distribution) { foreach ($distros as $_distribution) {
$dist = new \Froxlor\Config\ConfigParser($_distribution); $dist = new \Froxlor\Config\ConfigParser($_distribution);
$dist_display = $dist->distributionName . " " . $dist->distributionCodename . " (" . $dist->distributionVersion . ")"; $dist_display = $dist->distributionName . " " . $dist->distributionCodename . " (" . $dist->distributionVersion . ")";
if (!array_key_exists($dist_display, $distributions_select_data)) {
$distributions_select_data[$dist_display] = '';
}
$distributions_select_data[$dist_display] .= str_replace(".xml", "", strtolower(basename($_distribution))); $distributions_select_data[$dist_display] .= str_replace(".xml", "", strtolower(basename($_distribution)));
} }
// sort by distribution name // sort by distribution name
ksort($distributions_select_data); ksort($distributions_select_data);
$distributions_select = '';
foreach ($distributions_select_data as $dist_display => $dist_index) { foreach ($distributions_select_data as $dist_display => $dist_index) {
// create select-box-option // create select-box-option
$distributions_select .= \Froxlor\UI\HTML::makeoption($dist_display, $dist_index, $this->_data['distribution']); $distributions_select .= \Froxlor\UI\HTML::makeoption($dist_display, $dist_index, $this->_data['distribution'] ?? '');
// $this->_data['distribution'] // $this->_data['distribution']
} }
@@ -994,7 +999,6 @@ class FroxlorInstall
*/ */
private function _getSectionItemSelectbox($fieldname = null, $options = null, $style = "") private function _getSectionItemSelectbox($fieldname = null, $options = null, $style = "")
{ {
$groupname = $this->_lng['install'][$groupname];
$fieldlabel = $this->_lng['install'][$fieldname]; $fieldlabel = $this->_lng['install'][$fieldname];
$sectionitem = ""; $sectionitem = "";

View File

@@ -812,3 +812,53 @@ if (\Froxlor\Froxlor::isDatabaseVersion('202103240')) {
\Froxlor\Froxlor::updateToDbVersion('202106160'); \Froxlor\Froxlor::updateToDbVersion('202106160');
} }
if (\Froxlor\Froxlor::isDatabaseVersion('202106160')) {
showUpdateStep("Adjusting Let's Encrypt endpoint configuration to support ZeroSSL", true);
if (Settings::Get('system.letsencryptca') == 'testing') {
Settings::Set("system.letsencryptca", 'letsencrypt_test');
} else {
Settings::Set("system.letsencryptca", 'letsencrypt');
}
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202106270');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202106270')) {
showUpdateStep("Adding custom logo image settings", true);
Settings::AddNew("panel.logo_image_header", '');
Settings::AddNew("panel.logo_image_login", '');
lastStepStatus(0);
// Migrating old custom logo over, if exists
$custom_logo_file_old = \Froxlor\Froxlor::getInstallDir() . '/templates/Sparkle/assets/img/logo_custom.png';
if (file_exists($custom_logo_file_old)) {
showUpdateStep("Migrating existing custom logo to new settings", true);
$path = \Froxlor\Froxlor::getInstallDir().'/img/';
if (!is_dir($path) && !mkdir($path, 0775)) {
throw new \Exception("img directory does not exist and cannot be created");
}
if (!is_writable($path)) {
if (!chmod($path, '0775')) {
throw new \Exception("Cannot write to img directory");
}
}
// Save as new custom logo header
$save_to = 'logo_header.png';
copy($custom_logo_file_old, $path.$save_to);
Settings::Set("panel.logo_image_header", "img/{$save_to}?v=".time());
// Save as new custom logo login
$save_to = 'logo_login.png';
copy($custom_logo_file_old, $path.$save_to);
Settings::Set("panel.logo_image_login", "img/{$save_to}?v=".time());
lastStepStatus(0);
}
\Froxlor\Froxlor::updateToDbVersion('202107070');
}

View File

@@ -28,6 +28,12 @@ use Froxlor\FileDir;
class AcmeSh extends \Froxlor\Cron\FroxlorCron class AcmeSh extends \Froxlor\Cron\FroxlorCron
{ {
const ACME_PROVIDER = [
'letsencrypt' => "https://acme-v02.api.letsencrypt.org/directory",
'letsencrypt_test' => "https://acme-staging-v02.api.letsencrypt.org/directory",
'zerossl' => "https://acme.zerossl.com/v2/DV90"
];
private static $apiserver = ""; private static $apiserver = "";
private static $acmesh = "/root/.acme.sh/acme.sh"; private static $acmesh = "/root/.acme.sh/acme.sh";
@@ -71,7 +77,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
} }
// set server according to settings // set server according to settings
self::$apiserver = 'https://acme-' . (Settings::Get('system.letsencryptca') == 'testing' ? 'staging-' : '') . 'v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org/directory'; self::$apiserver = self::ACME_PROVIDER[Settings::Get('system.letsencryptca')];
// validate acme.sh installation // validate acme.sh installation
if (! self::checkInstall()) { if (! self::checkInstall()) {
@@ -306,7 +312,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
if (Settings::Get('system.letsencryptreuseold') != '1') { if (Settings::Get('system.letsencryptreuseold') != '1') {
$acmesh_cmd .= " --always-force-new-domain-key"; $acmesh_cmd .= " --always-force-new-domain-key";
} }
if (Settings::Get('system.letsencryptca') == 'testing') { if (Settings::Get('system.letsencryptca') == 'letsencrypt_test') {
$acmesh_cmd .= " --staging"; $acmesh_cmd .= " --staging";
} }
if ($force) { if ($force) {

View File

@@ -218,7 +218,7 @@ class Fpm
$openbasedir .= $_phpappendopenbasedir; $openbasedir .= $_phpappendopenbasedir;
} }
} }
$fpm_config .= 'php_admin_value[session.save_path] = ' . \Froxlor\FileDir::makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->domain['loginname'] . '/') . "\n";
$fpm_config .= 'php_admin_value[upload_tmp_dir] = ' . \Froxlor\FileDir::makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->domain['loginname'] . '/') . "\n"; $fpm_config .= 'php_admin_value[upload_tmp_dir] = ' . \Froxlor\FileDir::makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->domain['loginname'] . '/') . "\n";
$admin = $this->getAdminData($this->domain['adminid']); $admin = $this->getAdminData($this->domain['adminid']);
@@ -261,6 +261,11 @@ class Fpm
$fpm_config .= 'php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f ' . $this->domain['email'] . "\n"; $fpm_config .= 'php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f ' . $this->domain['email'] . "\n";
} }
// check for session.save_path, whether it has been specified by the user, if not, set a default
if (strpos($fpm_config, 'php_value[session.save_path]') === false && strpos($fpm_config, 'php_admin_value[session.save_path]') === false) {
$fpm_config .= 'php_admin_value[session.save_path] = ' . $this->getTempDir() . "\n";
}
// append custom phpfpm configuration // append custom phpfpm configuration
if (! empty($fpm_custom_config)) { if (! empty($fpm_custom_config)) {
$fpm_config .= "\n; Custom Configuration\n"; $fpm_config .= "\n; Custom Configuration\n";

View File

@@ -53,7 +53,7 @@ class Dns
$domain = $domain_id; $domain = $domain_id;
} }
if ($domain['isbinddomain'] != '1') { if (!isset($domain['isbinddomain']) || $domain['isbinddomain'] != '1') {
return; return;
} }
@@ -190,10 +190,24 @@ class Dns
'@', '@',
'www', 'www',
'*' '*'
] as $crceord) { ] as $crecord) {
if ($entry['type'] == 'CNAME' && $entry['record'] == '@' && (array_key_exists(md5($crceord), $required_entries['A']) || array_key_exists(md5($crceord), $required_entries['AAAA']))) { if ($entry['type'] == 'CNAME' && $entry['record'] == '@' && (array_key_exists(md5($crecord), $required_entries['A']) || array_key_exists(md5($crecord), $required_entries['AAAA']))) {
unset($required_entries['A'][md5($crceord)]); unset($required_entries['A'][md5($crecord)]);
unset($required_entries['AAAA'][md5($crceord)]); unset($required_entries['AAAA'][md5($crecord)]);
}
}
// also allow overriding of auto-generated values (imap,pop3,mail,smtp) if enabled in the settings
if (Settings::Get('system.dns_createmailentry')) {
foreach (array(
'imap',
'pop3',
'mail',
'smtp'
) as $crecord) {
if ($entry['type'] == 'CNAME' && $entry['record'] == $crecord && (array_key_exists(md5($crecord), $required_entries['A']) || array_key_exists(md5($crecord), $required_entries['AAAA']))) {
unset($required_entries['A'][md5($crecord)]);
unset($required_entries['AAAA'][md5($crecord)]);
}
} }
} }
$zonerecords[] = new DnsEntry($entry['record'], $entry['type'], $entry['content'], $entry['prio'], $entry['ttl']); $zonerecords[] = new DnsEntry($entry['record'], $entry['type'], $entry['content'], $entry['prio'], $entry['ttl']);

View File

@@ -10,7 +10,7 @@ final class Froxlor
const VERSION = '0.10.26'; const VERSION = '0.10.26';
// Database version (YYYYMMDDC where C is a daily counter) // Database version (YYYYMMDDC where C is a daily counter)
const DBVERSION = '202106160'; const DBVERSION = '202107070';
// Distribution branding-tag (used for Debian etc.) // Distribution branding-tag (used for Debian etc.)
const BRANDING = ''; const BRANDING = '';

View File

@@ -60,6 +60,13 @@ class SImExporter
public static function export() public static function export()
{ {
$settings_definitions = [];
foreach (\Froxlor\PhpHelper::loadConfigArrayDir('./actions/admin/settings/')['groups'] AS $group) {
foreach ($group['fields'] AS $field) {
$settings_definitions[$field['settinggroup']][$field['varname']] = $field;
}
}
$result_stmt = Database::query(" $result_stmt = Database::query("
SELECT * FROM `" . TABLE_PANEL_SETTINGS . "` ORDER BY `settingid` ASC SELECT * FROM `" . TABLE_PANEL_SETTINGS . "` ORDER BY `settingid` ASC
"); ");
@@ -69,13 +76,26 @@ class SImExporter
if (! in_array($index, self::$no_export)) { if (! in_array($index, self::$no_export)) {
$_data[$index] = $row['value']; $_data[$index] = $row['value'];
} }
if (array_key_exists($row['settinggroup'], $settings_definitions) && array_key_exists($row['varname'], $settings_definitions[$row['settinggroup']])) {
// Export image file
if ($settings_definitions[$row['settinggroup']][$row['varname']]['type'] === "image") {
if ($row['value'] === "") {
continue;
} }
$_data[$index.'.image_data'] = base64_encode(file_get_contents(explode('?', $row['value'], 2)[0]));
}
}
}
// add checksum for validation // add checksum for validation
$_data['_sha'] = sha1(var_export($_data, true)); $_data['_sha'] = sha1(var_export($_data, true));
$_export = json_encode($_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); $_export = json_encode($_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
if (! $_export) { if (! $_export) {
throw new \Exception("Error exporting settings: " . json_last_error_msg()); throw new \Exception("Error exporting settings: " . json_last_error_msg());
} }
return $_export; return $_export;
} }
@@ -120,6 +140,26 @@ class SImExporter
} }
// store new data // store new data
foreach ($_data as $index => $value) { foreach ($_data as $index => $value) {
$index_split = explode('.', $index, 3);
// Catch image_data and save it
if (isset($index_split[2]) && $index_split[2] === 'image_data' && !empty($_data[$index_split[0].'.'.$index_split[1]])) {
$path = \Froxlor\Froxlor::getInstallDir().'/img/';
if (!is_dir($path) && !mkdir($path, '0775')) {
throw new \Exception("img directory does not exist and cannot be created");
}
// Make sure we can write to the upload directory
if (!is_writable($path)) {
if (!chmod($path, '0775')) {
throw new \Exception("Cannot write to img directory");
}
}
file_put_contents(\Froxlor\Froxlor::getInstallDir() . '/' . explode('?', $_data[$index_split[0].'.'.$index_split[1]], 2)[0], base64_decode($value));
continue;
}
Settings::Set($index, $value); Settings::Set($index, $value);
} }
// save to DB // save to DB

View File

@@ -367,4 +367,67 @@ class Store
return $returnvalue; return $returnvalue;
} }
public static function storeSettingImage($fieldname, $fielddata)
{
if (isset($fielddata['settinggroup'], $fielddata['varname']) && is_array($fielddata) && $fielddata['settinggroup'] !== '' && $fielddata['varname'] !== '') {
$save_to = null;
$path = \Froxlor\Froxlor::getInstallDir().'/img/';
// New file?
if ($_FILES[$fieldname]['tmp_name']) {
// Make sure upload directory exists
if (!is_dir($path) && !mkdir($path, '0775')) {
throw new \Exception("img directory does not exist and cannot be created");
}
// Make sure we can write to the upload directory
if (!is_writable($path)) {
if (!chmod($path, '0775')) {
throw new \Exception("Cannot write to img directory");
}
}
// Make sure mime-type matches an image
if (!in_array(mime_content_type($_FILES[$fieldname]['tmp_name']), ['image/jpeg','image/jpg','image/png','image/gif'])) {
throw new \Exception("Uploaded file not a valid image");
}
// Determine file extension
$spl = explode('.', $_FILES[$fieldname]['name']);
$file_extension = strtolower(array_pop($spl));
unset($spl);
// Move file
if (!move_uploaded_file($_FILES[$fieldname]['tmp_name'], $path.$fielddata['image_name'].'.'.$file_extension)) {
throw new \Exception("Unable to save image to img folder");
}
$save_to = 'img/'.$fielddata['image_name'].'.'.$file_extension.'?v='.time();
}
// Delete file?
if ($fielddata['value'] !== "" && array_key_exists($fieldname.'_delete', $_POST) && $_POST[$fieldname.'_delete']) {
@unlink(\Froxlor\Froxlor::getInstallDir() . '/' . explode('?', $fielddata['value'], 2)[0]);
$save_to = '';
}
// Nothing changed
if ($save_to === null) {
return array(
$fielddata['settinggroup'] . '.' . $fielddata['varname'] => $fielddata['value']
);
}
if (Settings::Set($fielddata['settinggroup'] . '.' . $fielddata['varname'], $save_to) === false) {
return false;
}
return array(
$fielddata['settinggroup'] . '.' . $fielddata['varname'] => $save_to
);
}
return false;
}
} }

View File

@@ -52,6 +52,12 @@ class Data
return $newfieldvalue; return $newfieldvalue;
} }
public static function getFormFieldDataImage($fieldname, $fielddata, $input)
{
// We always make the system think we have new data to trigger the save function where we actually check everything
return time();
}
public static function manipulateFormFieldDataDate($fieldname, $fielddata, $newfieldvalue) public static function manipulateFormFieldDataDate($fieldname, $fielddata, $newfieldvalue)
{ {
if (isset($fielddata['date_timestamp']) && $fielddata['date_timestamp'] === true) { if (isset($fielddata['date_timestamp']) && $fielddata['date_timestamp'] === true) {

View File

@@ -89,6 +89,15 @@ class Fields
return $returnvalue; return $returnvalue;
} }
public static function getFormFieldOutputImage($fieldname, $fielddata, $do_show = true)
{
global $lng;
$label = $fielddata['label'];
$value = htmlentities($fielddata['value']);
eval("\$returnvalue = \"" . \Froxlor\UI\Template::getTemplate("formfields/image", true) . "\";");
return $returnvalue;
}
public static function getFormFieldOutputDate($fieldname, $fielddata, $do_show = true) public static function getFormFieldOutputDate($fieldname, $fielddata, $do_show = true)
{ {
if (isset($fielddata['date_timestamp']) && $fielddata['date_timestamp'] === true) { if (isset($fielddata['date_timestamp']) && $fielddata['date_timestamp'] === true) {

View File

@@ -74,7 +74,7 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
]]> ]]>
</content> </content>
</file> </file>
<command><![CDATA[/etc/init.d/apache2 restart]]></command> <command><![CDATA[service apache2 restart]]></command>
</daemon> </daemon>
<!-- HTTP Lighttpd --> <!-- HTTP Lighttpd -->
<daemon name="lighttpd" title="LigHTTPd"> <daemon name="lighttpd" title="LigHTTPd">
@@ -138,7 +138,7 @@ include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
</command> </command>
<command><![CDATA[lighty-disable-mod cgi]]></command> <command><![CDATA[lighty-disable-mod cgi]]></command>
<command><![CDATA[lighty-disable-mod fastcgi]]></command> <command><![CDATA[lighty-disable-mod fastcgi]]></command>
<command><![CDATA[/etc/init.d/lighttpd restart]]></command> <command><![CDATA[service lighttpd restart]]></command>
</daemon> </daemon>
<!-- HTTP Nginx --> <!-- HTTP Nginx -->
<daemon name="nginx" title="nginx"> <daemon name="nginx" title="nginx">
@@ -354,7 +354,6 @@ exit "$RETVAL"
</visibility> </visibility>
<content><![CDATA[/etc/init.d/php-fcgi restart]]></content> <content><![CDATA[/etc/init.d/php-fcgi restart]]></content>
</command> </command>
<command><![CDATA[/etc/init.d/nginx restart]]></command>
</daemon> </daemon>
</service> </service>
<!--DNS --> <!--DNS -->
@@ -366,7 +365,7 @@ exit "$RETVAL"
<command><![CDATA[touch {{settings.system.bindconf_directory}}froxlor_bind.conf]]></command> <command><![CDATA[touch {{settings.system.bindconf_directory}}froxlor_bind.conf]]></command>
<command><![CDATA[chown bind:0 {{settings.system.bindconf_directory}}froxlor_bind.conf]]></command> <command><![CDATA[chown bind:0 {{settings.system.bindconf_directory}}froxlor_bind.conf]]></command>
<command><![CDATA[chmod 0644 {{settings.system.bindconf_directory}}froxlor_bind.conf]]></command> <command><![CDATA[chmod 0644 {{settings.system.bindconf_directory}}froxlor_bind.conf]]></command>
<command><![CDATA[/etc/init.d/bind9 restart]]></command> <command><![CDATA[service bind9 restart]]></command>
</daemon> </daemon>
<daemon name="powerdns" title="PowerDNS (standalone)"> <daemon name="powerdns" title="PowerDNS (standalone)">
<install><![CDATA[apt-get install pdns-server pdns-backend-mysql]]></install> <install><![CDATA[apt-get install pdns-server pdns-backend-mysql]]></install>
@@ -908,7 +907,7 @@ gmysql-password=
]]> ]]>
</content> </content>
</file> </file>
<command><![CDATA[/etc/init.d/pdns restart]]></command> <command><![CDATA[service pdns restart]]></command>
</daemon> </daemon>
<daemon name="powerdns_bind" <daemon name="powerdns_bind"
title="PowerDNS via bind-backend"> title="PowerDNS via bind-backend">
@@ -1455,7 +1454,7 @@ bind-check-interval=180
]]> ]]>
</content> </content>
</file> </file>
<command><![CDATA[/etc/init.d/pdns restart]]></command> <command><![CDATA[service pdns restart]]></command>
</daemon> </daemon>
</service> </service>
<!-- SMTP services --> <!-- SMTP services -->
@@ -1578,7 +1577,7 @@ root: root@<SERVERNAME>
</files> </files>
<commands index="3"> <commands index="3">
<command><![CDATA[newaliases]]></command> <command><![CDATA[newaliases]]></command>
<command><![CDATA[/etc/init.d/postfix restart]]></command> <command><![CDATA[service postfix restart]]></command>
</commands> </commands>
</general> </general>
<!-- postfix with dovecot --> <!-- postfix with dovecot -->
@@ -3299,7 +3298,7 @@ plugin {
</file> </file>
</files> </files>
<commands index="1"> <commands index="1">
<command><![CDATA[/etc/init.d/dovecot restart]]></command> <command><![CDATA[service dovecot restart]]></command>
</commands> </commands>
</general> </general>
<!-- Dovecot with postfix --> <!-- Dovecot with postfix -->
@@ -3722,7 +3721,7 @@ TLSVerifyClient off
]]> ]]>
</content> </content>
</file> </file>
<command><![CDATA[/etc/init.d/proftpd restart]]></command> <command><![CDATA[service proftpd restart]]></command>
</daemon> </daemon>
<!-- Pureftpd --> <!-- Pureftpd -->
<daemon name="pureftpd" title="PureFTPd"> <daemon name="pureftpd" title="PureFTPd">
@@ -3948,7 +3947,7 @@ UPLOADGID=
]]> ]]>
</content> </content>
</file> </file>
<command><![CDATA[/etc/init.d/pure-ftpd-mysql restart]]></command> <command><![CDATA[service pure-ftpd-mysql restart]]></command>
</daemon> </daemon>
</service> </service>
<!-- System tools/services --> <!-- System tools/services -->
@@ -4088,7 +4087,7 @@ aliases: files
<commands index="5"> <commands index="5">
<visibility mode="equals" value="apache2">{{settings.system.webserver}} <visibility mode="equals" value="apache2">{{settings.system.webserver}}
</visibility> </visibility>
<command><![CDATA[/etc/init.d/apache2 restart]]></command> <command><![CDATA[service apache2 restart]]></command>
</commands> </commands>
<!-- instead of just restarting apache, we let the cronjob do all the <!-- instead of just restarting apache, we let the cronjob do all the
dirty work --> dirty work -->

View File

@@ -380,11 +380,8 @@ if (! array_key_exists('variants', $_themeoptions) || ! array_key_exists($themev
// check for custom header-graphic // check for custom header-graphic
$hl_path = 'templates/' . $theme . '/assets/img'; $hl_path = 'templates/' . $theme . '/assets/img';
$header_logo = $hl_path . '/logo.png'; $header_logo = Settings::Get('panel.logo_image_header') ?: $hl_path . '/logo.png';
$header_logo_login = Settings::Get('panel.logo_image_login') ?: $hl_path . '/logo.png';
if (file_exists($hl_path . '/logo_custom.png')) {
$header_logo = $hl_path . '/logo_custom.png';
}
/** /**
* Redirects to index.php (login page) if no session exists * Redirects to index.php (login page) if no session exists

View File

@@ -1839,8 +1839,8 @@ $lng['error']['sslredirectonlypossiblewithsslipport'] = 'Using Let\'s Encrypt is
$lng['error']['nowildcardwithletsencrypt'] = 'Let\'s Encrypt cannot handle wildcard-domains using ACME in froxlor (requires dns-challenge), sorry. Please set the ServerAlias to WWW or disable it completely'; $lng['error']['nowildcardwithletsencrypt'] = 'Let\'s Encrypt cannot handle wildcard-domains using ACME in froxlor (requires dns-challenge), sorry. Please set the ServerAlias to WWW or disable it completely';
$lng['panel']['letsencrypt'] = 'Using Let\'s encrypt'; $lng['panel']['letsencrypt'] = 'Using Let\'s encrypt';
$lng['crondesc']['cron_letsencrypt'] = 'updating Let\'s Encrypt certificates'; $lng['crondesc']['cron_letsencrypt'] = 'updating Let\'s Encrypt certificates';
$lng['serversettings']['letsencryptca']['title'] = "Let's Encrypt environment"; $lng['serversettings']['letsencryptca']['title'] = "ACME environment";
$lng['serversettings']['letsencryptca']['description'] = "Environment to be used for Let's Encrypt certificates."; $lng['serversettings']['letsencryptca']['description'] = "Environment to be used for Let's Encrypt / ZeroSSL certificates.";
$lng['serversettings']['letsencryptcountrycode']['title'] = "Let's Encrypt country code"; $lng['serversettings']['letsencryptcountrycode']['title'] = "Let's Encrypt country code";
$lng['serversettings']['letsencryptcountrycode']['description'] = "2 letter country code used to generate Let's Encrypt certificates."; $lng['serversettings']['letsencryptcountrycode']['description'] = "2 letter country code used to generate Let's Encrypt certificates.";
$lng['serversettings']['letsencryptstate']['title'] = "Let's Encrypt state"; $lng['serversettings']['letsencryptstate']['title'] = "Let's Encrypt state";
@@ -2117,3 +2117,9 @@ $lng['privacy'] = 'Privacy policy';
$lng['serversettings']['privacy_url']['title'] = 'URL to privacy policy'; $lng['serversettings']['privacy_url']['title'] = 'URL to privacy policy';
$lng['serversettings']['privacy_url']['description'] = 'Specify an URL to your privacy policy site / imprint site. The link will be visible on the login screen and on the footer when logged in.'; $lng['serversettings']['privacy_url']['description'] = 'Specify an URL to your privacy policy site / imprint site. The link will be visible on the login screen and on the footer when logged in.';
$lng['admin']['domaindefaultalias'] = 'Default ServerAlias value for new domains'; $lng['admin']['domaindefaultalias'] = 'Default ServerAlias value for new domains';
$lng['serversettings']['logo_image_header']['title'] = 'Logo Image (Header)';
$lng['serversettings']['logo_image_header']['description'] = 'Upload your own logo image to be shown in the header after login (recommended height 30px)';
$lng['serversettings']['logo_image_login']['title'] = 'Logo Image (Login)';
$lng['serversettings']['logo_image_login']['description'] = 'Upload your own logo image to be shown during login';
$lng['panel']['image_field_delete'] = 'Delete the existing current image';

View File

@@ -1490,8 +1490,8 @@ $lng['error']['sslredirectonlypossiblewithsslipport'] = 'Die Nutzung von Let\'s
$lng['error']['nowildcardwithletsencrypt'] = 'Let\'s Encrypt kann mittels ACME Wildcard-Domains nur via DNS validieren, sorry. Bitte den ServerAlias auf WWW setzen oder deaktivieren'; $lng['error']['nowildcardwithletsencrypt'] = 'Let\'s Encrypt kann mittels ACME Wildcard-Domains nur via DNS validieren, sorry. Bitte den ServerAlias auf WWW setzen oder deaktivieren';
$lng['panel']['letsencrypt'] = 'Benutzt Let\'s encrypt'; $lng['panel']['letsencrypt'] = 'Benutzt Let\'s encrypt';
$lng['crondesc']['cron_letsencrypt'] = 'Aktualisierung der Let\'s Encrypt Zertifikate'; $lng['crondesc']['cron_letsencrypt'] = 'Aktualisierung der Let\'s Encrypt Zertifikate';
$lng['serversettings']['letsencryptca']['title'] = "Let's Encrypt Umgebung"; $lng['serversettings']['letsencryptca']['title'] = "ACME Umgebung";
$lng['serversettings']['letsencryptca']['description'] = "Let's Encrypt - Umgebung, welche genutzt wird um Zertifikate zu bestellen."; $lng['serversettings']['letsencryptca']['description'] = "Umgebung, welche genutzt wird um Zertifikate zu bestellen.";
$lng['serversettings']['letsencryptcountrycode']['title'] = "Let's Encrypt Ländercode"; $lng['serversettings']['letsencryptcountrycode']['title'] = "Let's Encrypt Ländercode";
$lng['serversettings']['letsencryptcountrycode']['description'] = "2 - stelliger Ländercode, welcher benutzt wird um Let's Encrypt - Zertifikate zu bestellen."; $lng['serversettings']['letsencryptcountrycode']['description'] = "2 - stelliger Ländercode, welcher benutzt wird um Let's Encrypt - Zertifikate zu bestellen.";
$lng['serversettings']['letsencryptstate']['title'] = "Let's Encrypt Bundesland"; $lng['serversettings']['letsencryptstate']['title'] = "Let's Encrypt Bundesland";
@@ -1763,3 +1763,9 @@ $lng['privacy'] = 'Datenschutzerklärung';
$lng['serversettings']['privacy_url']['title'] = 'URL zur Datenschutzerklärung'; $lng['serversettings']['privacy_url']['title'] = 'URL zur Datenschutzerklärung';
$lng['serversettings']['privacy_url']['description'] = 'Die URL zur Datenschutzerklärungs-Seite. Der Link ist auf der Login-Seite und wenn eingeloggt, in der Fußzeile sichtbar.'; $lng['serversettings']['privacy_url']['description'] = 'Die URL zur Datenschutzerklärungs-Seite. Der Link ist auf der Login-Seite und wenn eingeloggt, in der Fußzeile sichtbar.';
$lng['admin']['domaindefaultalias'] = 'Standard ServerAlias-Angabe für neue Domains'; $lng['admin']['domaindefaultalias'] = 'Standard ServerAlias-Angabe für neue Domains';
$lng['serversettings']['logo_image_header']['title'] = 'Logo Bild (Header)';
$lng['serversettings']['logo_image_header']['description'] = 'Das hochgeladene Bild wird als Logo oben links nach dem Login angezeigt (empfohlene Höhe sind 30px)';
$lng['serversettings']['logo_image_login']['title'] = 'Logo Bild (Login)';
$lng['serversettings']['logo_image_login']['description'] = 'Das hochgeladene Bild wird als Logo während des Logins angezeigt';
$lng['panel']['image_field_delete'] = 'Das momentan vorhandene Bild löschen';

View File

@@ -1,7 +1,7 @@
$header $header
<article class="login bradius"> <article class="login bradius">
<header class="dark"> <header class="dark">
<img src="{$header_logo}" alt="Froxlor Server Management Panel" /> <img src="{$header_logo_login}" alt="Froxlor Server Management Panel" />
</header> </header>
<section class="loginsec"> <section class="loginsec">
<form method="post" action="{$filename}" enctype="application/x-www-form-urlencoded"> <form method="post" action="{$filename}" enctype="application/x-www-form-urlencoded">

View File

@@ -1,5 +1,5 @@
$header $header
<form method="post" action="$filename" enctype="application/x-www-form-urlencoded"> <form method="post" action="$filename" enctype="multipart/form-data">
<input type="hidden" name="send" value="send" /> <input type="hidden" name="send" value="send" />
<input type="hidden" name="s" value="$s" /> <input type="hidden" name="s" value="$s" />
<input type="hidden" name="page" value="$page" /> <input type="hidden" name="page" value="$page" />

View File

@@ -77,7 +77,11 @@ strong {
} }
header img { header img {
padding: 10px 0 10px 10px; padding: 10px;
}
.login header img {
margin: 0 auto;
display: block;
} }
img.small { img.small {
@@ -1745,3 +1749,9 @@ td.size-50 {
.footer-link:last-child:after { .footer-link:last-child:after {
content: ""; content: "";
} }
.field-image-preview {
max-width: 300px;
max-height: 500px;
margin-bottom: 10px;
}

11
templates/Sparkle/formfields/image.tpl vendored Normal file
View File

@@ -0,0 +1,11 @@
<tr>
<td>{$label}</td>
<td>
<if $value>
<img src="/{$value}" alt="Current Image" class="field-image-preview"><br>
<input type="checkbox" value="1" name="{$fieldname}_delete" /> {$lng['panel']['image_field_delete']}
<br><br>
</if>
<input <if $do_show == 0>disabled="disabled"</if> type="file" class="file" name="{$fieldname}" accept="image/jpeg, image/jpg, image/png, image/gif" />
</td>
</tr>

View File

@@ -1,7 +1,7 @@
$header $header
<article class="login bradius"> <article class="login bradius">
<header class="dark"> <header class="dark">
<img src="{$header_logo}" alt="Froxlor Server Management Panel" /> <img src="{$header_logo_login}" alt="Froxlor Server Management Panel" />
</header> </header>
<if $message != ''> <if $message != ''>
<div class="errorcontainer bradius"> <div class="errorcontainer bradius">

View File

@@ -1,7 +1,7 @@
$header $header
<article class="login bradius"> <article class="login bradius">
<header class="dark"> <header class="dark">
<img src="{$header_logo}" alt="Froxlor Server Management Panel" /> <img src="{$header_logo_login}" alt="Froxlor Server Management Panel" />
</header> </header>
<if $update_in_progress !== ''> <if $update_in_progress !== ''>

View File

@@ -1,6 +1,6 @@
<article class="login bradius"> <article class="login bradius">
<header class="dark"> <header class="dark">
<img src="{$header_logo}" alt="{t}Froxlor Server Management Panel{/t}" /> <img src="{$header_logo_login}" alt="{t}Froxlor Server Management Panel{/t}" />
</header> </header>
{if isset($successmessage)} {if isset($successmessage)}

View File

@@ -1,7 +1,7 @@
$header $header
<article class="login bradius"> <article class="login bradius">
<header class="dark"> <header class="dark">
<img src="{$header_logo}" alt="Froxlor Server Management Panel" /> <img src="{$header_logo_login}" alt="Froxlor Server Management Panel" />
</header> </header>
<if $message != ''> <if $message != ''>
<div class="errorcontainer bradius"> <div class="errorcontainer bradius">