Compare commits

..

13 Commits

Author SHA1 Message Date
Michael Kaufmann
1debe9d939 set version to 2.1.0-rc1
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-11-03 13:44:49 +01:00
Michael Kaufmann
3d2e81b457 mark lighttpd as deprecated
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-11-03 13:39:15 +01:00
Michael Kaufmann
ac759cd9a4 make ssl-cert and ssl-key optional only if a system fallback is specified, else they are required in IpsAndPorts.add() and IpsAndPorts.update()
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-11-03 10:07:53 +01:00
Michael Kaufmann
05c77929e4 add unconfigured domain template; enhance contrast of tables in light-theme
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-11-03 09:53:18 +01:00
Michael Kaufmann
cefd9226bd fix possible missing _ecc suffix of let's encrypt folder when cleaning up after deleting a domain
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-11-02 11:33:08 +01:00
Michael Kaufmann
762f295d3d Show nice note if requested domain is 'unknown' to froxlor and thus is being lead to its vhost
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-10-31 16:43:21 +01:00
Michael Kaufmann
d3e6063027 more password-suggestion fields modernized as the others; little beautifications here and there
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-10-31 14:55:02 +01:00
Michael Kaufmann
f18c14e119 update readme (cosmetics)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-10-30 09:27:08 +01:00
Michael Kaufmann
77bcd10729 removed deprecated/old x-xss-protection http-header
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-10-25 15:03:57 +02:00
Michael Kaufmann
6ee990af0a switch from huntr.dev to github security advisories as huntr drops support for non-AI/ML projects
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-10-24 23:08:48 +02:00
Michael Kaufmann
a3fe37b69b use absolute path in settings-export to avoid errors when invoking the cli scripts from out of froxlor's homedir
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-10-24 19:00:09 +02:00
Michael Kaufmann
56388ede54 fix unescaped quotes for input-fields in settings
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-10-18 21:04:16 +02:00
Michael Kaufmann
b98035bf3a fix froxlor:update cli command; fix html-syntax issue in updater-result-template which leads to a white page after update
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2023-10-18 17:08:30 +02:00
30 changed files with 189 additions and 100 deletions

View File

@@ -34,19 +34,13 @@ You may find help in the following places:
The froxlor community discord server can be found here: https://discord.froxlor.org
### IRC
froxlor may be found on libera.chat, channel #froxlor:
irc://irc.libera.chat/froxlor
### Forum
The community is located on https://forum.froxlor.org/
### Wiki
### Documentation
More documentation may be found in the froxlor - documentation:
https://docs.froxlor.org/
The documentation may be found at https://docs.froxlor.org/
## License

View File

@@ -27,7 +27,7 @@ With that, good luck hacking us ;)
### Vulnerabilities we accept
Only reproducable issues on a default/clean setup from the latest stable release of a supported version will be accepted.
Only reproducible issues on a default/clean setup from the latest stable release of a supported version will be accepted.
## Non-Qualifying Vulnerabilities
@@ -45,4 +45,4 @@ Only reproducable issues on a default/clean setup from the latest stable release
## Reporting a Vulnerability
If you think you have found a vulnerability in froxlor, please head over to [https://huntr.dev/repos/froxlor/froxlor](https://huntr.dev/repos/froxlor/froxlor) and use the reporting possibilities there as we are funding the prize-pot for froxlor on this platform. Also, please give us appropriate time to fix the issue and build update-packages before publishing anything into the wild. Alternatively you can send us an email to [team@froxlor.org](team@froxlor.org).
If you think you have found a vulnerability in froxlor, please head over to [https://github.com/Froxlor/Froxlor/security/advisories](https://github.com/Froxlor/Froxlor/security/advisories/new) and use the reporting possibilities there. Also, please give us appropriate time to fix the issue and build update-packages before publishing anything into the wild. Alternatively you can email us to [team@froxlor.org](team@froxlor.org).

View File

@@ -679,7 +679,7 @@ opcache.validate_timestamps'),
('system', 'distribution', ''),
('system', 'update_channel', 'stable'),
('system', 'updatecheck_data', ''),
('system', 'update_notify_last', '2.1.0-beta2'),
('system', 'update_notify_last', '2.1.0-rc1'),
('system', 'traffictool', 'goaccess'),
('system', 'req_limit_per_interval', 60),
('system', 'req_limit_interval', 60),
@@ -727,7 +727,7 @@ opcache.validate_timestamps'),
('panel', 'logo_overridecustom', '0'),
('panel', 'settings_mode', '0'),
('panel', 'menu_collapsed', '1'),
('panel', 'version', '2.1.0-beta2'),
('panel', 'version', '2.1.0-rc1'),
('panel', 'db_version', '202305240');

View File

@@ -103,3 +103,8 @@ if (Froxlor::isFroxlorVersion('2.1.0-beta1')) {
Froxlor::updateToVersion('2.1.0-beta2');
}
if (Froxlor::isFroxlorVersion('2.1.0-beta2')) {
Update::showUpdateStep("Updating from 2.1.0-beta2 to 2.1.0-rc1", false);
Froxlor::updateToVersion('2.1.0-rc1');
}

View File

@@ -176,8 +176,9 @@ class IpsAndPorts extends ApiCommand implements ResourceEntity
if ((int)Settings::Get('system.use_ssl') == 1) {
$ssl = (bool)$this->getBoolParam('ssl', true, 0);
$ssl_cert_file = Validate::validate($this->getParam('ssl_cert_file', !$ssl, ''), 'ssl_cert_file', '', '', [], true);
$ssl_key_file = Validate::validate($this->getParam('ssl_key_file', !$ssl, ''), 'ssl_key_file', '', '', [], true);
$cert_optional = !($ssl && empty(Settings::Get('system.ssl_cert_file')));
$ssl_cert_file = Validate::validate($this->getParam('ssl_cert_file', $cert_optional, ''), 'ssl_cert_file', '', '', [], true);
$ssl_key_file = Validate::validate($this->getParam('ssl_key_file', $cert_optional, ''), 'ssl_key_file', '', '', [], true);
$ssl_ca_file = Validate::validate($this->getParam('ssl_ca_file', true, ''), 'ssl_ca_file', '', '', [], true);
$ssl_cert_chainfile = Validate::validate($this->getParam('ssl_cert_chainfile', true, ''), 'ssl_cert_chainfile', '', '', [], true);
$sslss = $this->getParam('ssl_specialsettings', true, '');
@@ -415,8 +416,9 @@ class IpsAndPorts extends ApiCommand implements ResourceEntity
if ((int)Settings::Get('system.use_ssl') == 1) {
$ssl = (bool)$this->getBoolParam('ssl', true, $result['ssl']);
$ssl_cert_file = Validate::validate($this->getParam('ssl_cert_file', !$ssl, $result['ssl_cert_file']), 'ssl_cert_file', '', '', [], true);
$ssl_key_file = Validate::validate($this->getParam('ssl_key_file', !$ssl, $result['ssl_key_file']), 'ssl_key_file', '', '', [], true);
$cert_optional = !($ssl && empty(Settings::Get('system.ssl_cert_file')));
$ssl_cert_file = Validate::validate($this->getParam('ssl_cert_file', $cert_optional, $result['ssl_cert_file']), 'ssl_cert_file', '', '', [], true);
$ssl_key_file = Validate::validate($this->getParam('ssl_key_file', $cert_optional, $result['ssl_key_file']), 'ssl_key_file', '', '', [], true);
$ssl_ca_file = Validate::validate($this->getParam('ssl_ca_file', true, $result['ssl_ca_file']), 'ssl_ca_file', '', '', [], true);
$ssl_cert_chainfile = Validate::validate($this->getParam('ssl_cert_chainfile', true, $result['ssl_cert_chainfile']), 'ssl_cert_chainfile', '', '', [], true);
$sslss = $this->getParam('ssl_specialsettings', true, $result['ssl_specialsettings']);

View File

@@ -56,7 +56,7 @@ final class UpdateCommand extends CliCommand
// database update only
if ($input->getOption('database')) {
$result = $this->validateRequirements($input, $output, true);
$result = $this->validateRequirements($output, true);
if ($result == self::SUCCESS) {
if (Froxlor::hasUpdates() || Froxlor::hasDbUpdates()) {
$output->writeln('<info>' . lng('updates.dbupdate_required') . '</>');
@@ -77,7 +77,7 @@ final class UpdateCommand extends CliCommand
return $result;
}
$result = $this->validateRequirements($input, $output);
$result = $this->validateRequirements($output);
if ($result != self::SUCCESS) {
// requirements failed, exit

View File

@@ -515,13 +515,7 @@ class Apache extends HttpConfigBase
*/
private function createStandardDirectoryEntry()
{
$vhosts_folder = '';
if (is_dir(Settings::Get('system.apacheconf_vhost'))) {
$vhosts_folder = FileDir::makeCorrectDir(Settings::Get('system.apacheconf_vhost'));
} else {
$vhosts_folder = FileDir::makeCorrectDir(dirname(Settings::Get('system.apacheconf_vhost')));
}
$vhosts_filename = FileDir::makeCorrectFile($vhosts_folder . '/05_froxlor_dirfix_nofcgid.conf');
$vhosts_filename = $this->getCustomVhostFilename('05_froxlor_dirfix_nofcgid.conf');
if (!isset($this->virtualhosts_data[$vhosts_filename])) {
$this->virtualhosts_data[$vhosts_filename] = '';
@@ -545,7 +539,7 @@ class Apache extends HttpConfigBase
}
$this->virtualhosts_data[$vhosts_filename] .= ' </Directory>' . "\n";
$ocsp_cache_filename = FileDir::makeCorrectFile($vhosts_folder . '/03_froxlor_ocsp_cache.conf');
$ocsp_cache_filename = $this->getCustomVhostFilename('03_froxlor_ocsp_cache.conf');
if (Settings::Get('system.use_ssl') == '1' && Settings::Get('system.apache24') == 1) {
$this->virtualhosts_data[$ocsp_cache_filename] = 'SSLStaplingCache ' . Settings::Get('system.apache24_ocsp_cache_path') . "\n";
} else {
@@ -562,14 +556,7 @@ class Apache extends HttpConfigBase
private function createStandardErrorHandler()
{
if (Settings::Get('defaultwebsrverrhandler.enabled') == '1' && (Settings::Get('defaultwebsrverrhandler.err401') != '' || Settings::Get('defaultwebsrverrhandler.err403') != '' || Settings::Get('defaultwebsrverrhandler.err404') != '' || Settings::Get('defaultwebsrverrhandler.err500') != '')) {
$vhosts_folder = '';
if (is_dir(Settings::Get('system.apacheconf_vhost'))) {
$vhosts_folder = FileDir::makeCorrectDir(Settings::Get('system.apacheconf_vhost'));
} else {
$vhosts_folder = FileDir::makeCorrectDir(dirname(Settings::Get('system.apacheconf_vhost')));
}
$vhosts_filename = FileDir::makeCorrectFile($vhosts_folder . '/05_froxlor_default_errorhandler.conf');
$vhosts_filename = $this->getCustomVhostFilename('05_froxlor_default_errorhandler.conf');
if (!isset($this->virtualhosts_data[$vhosts_filename])) {
$this->virtualhosts_data[$vhosts_filename] = '';

View File

@@ -202,4 +202,13 @@ class HttpConfigBase
}
return FileDir::makeCorrectFile(Settings::Get('system.apacheconf_vhost') . '/' . $filename);
}
protected function getCustomVhostFilename(string $name)
{
$vhosts_folder = FileDir::makeCorrectDir(dirname(Settings::Get('system.apacheconf_vhost')));
if (is_dir(Settings::Get('system.apacheconf_vhost'))) {
$vhosts_folder = FileDir::makeCorrectDir(Settings::Get('system.apacheconf_vhost'));
}
return FileDir::makeCorrectFile($vhosts_folder . '/' . $name);
}
}

View File

@@ -1161,14 +1161,7 @@ class Nginx extends HttpConfigBase
private function createStandardErrorHandler()
{
if (Settings::Get('defaultwebsrverrhandler.enabled') == '1' && (Settings::Get('defaultwebsrverrhandler.err401') != '' || Settings::Get('defaultwebsrverrhandler.err403') != '' || Settings::Get('defaultwebsrverrhandler.err404') != '' || Settings::Get('defaultwebsrverrhandler.err500') != '')) {
$vhosts_folder = '';
if (is_dir(Settings::Get('system.apacheconf_vhost'))) {
$vhosts_folder = FileDir::makeCorrectDir(Settings::Get('system.apacheconf_vhost'));
} else {
$vhosts_folder = FileDir::makeCorrectDir(dirname(Settings::Get('system.apacheconf_vhost')));
}
$vhosts_filename = FileDir::makeCorrectFile($vhosts_folder . '/05_froxlor_default_errorhandler.conf');
$vhosts_filename = $this->getCustomVhostFilename('05_froxlor_default_errorhandler.conf');
if (!isset($this->nginx_data[$vhosts_filename])) {
$this->nginx_data[$vhosts_filename] = '';

View File

@@ -320,12 +320,15 @@ class Domain
* @throws \Exception
*/
public static function triggerLetsEncryptCSRForAliasDestinationDomain(
int $aliasDestinationDomainID,
int $aliasDestinationDomainID,
FroxlorLogger $log
) {
if ($aliasDestinationDomainID > 0) {
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_INFO,
"LetsEncrypt CSR triggered for domain ID " . $aliasDestinationDomainID);
$log->logAction(
FroxlorLogger::ADM_ACTION,
LOG_INFO,
"LetsEncrypt CSR triggered for domain ID " . $aliasDestinationDomainID
);
$upd_stmt = Database::prepare("UPDATE
`" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
SET
@@ -349,15 +352,20 @@ class Domain
$acmesh = AcmeSh::getAcmeSh();
if (file_exists($acmesh)) {
$certificate_folder = AcmeSh::getWorkingDirFromEnv($domainname);
if (file_exists($certificate_folder)) {
$certificate_ecc_folder = AcmeSh::getWorkingDirFromEnv($domainname, true);
if (file_exists($certificate_folder) || file_exists($certificate_ecc_folder)) {
$params = " --remove -d " . $domainname;
if (Settings::Get('system.leecc') > 0) {
if (file_exists($certificate_ecc_folder)) {
$params .= " --ecc";
}
// run remove command
FileDir::safe_exec($acmesh . $params);
// remove certificates directory
FileDir::safe_exec('rm -rf ' . $certificate_folder);
if (file_exists($certificate_folder)) {
FileDir::safe_exec('rm -rf ' . $certificate_folder);
} elseif (file_exists($certificate_ecc_folder)) {
FileDir::safe_exec('rm -rf ' . $certificate_ecc_folder);
}
}
}
return true;

View File

@@ -31,7 +31,7 @@ final class Froxlor
{
// Main version variable
const VERSION = '2.1.0-beta2';
const VERSION = '2.1.0-rc1';
// Database version (YYYYMMDDC where C is a daily counter)
const DBVERSION = '202305240';

View File

@@ -85,7 +85,7 @@ class Update
self::$update_tasks[self::$task_counter]['result'] = 1;
break;
default:
self::$update_tasks[self::$task_counter]['result'] = -1;
self::$update_tasks[self::$task_counter]['result'] = -1;
break;
}

View File

@@ -65,7 +65,7 @@ class SImExporter
public static function export()
{
$settings_definitions = [];
foreach (PhpHelper::loadConfigArrayDir('./actions/admin/settings/')['groups'] as $group) {
foreach (PhpHelper::loadConfigArrayDir(Froxlor::getInstallDir() . '/actions/admin/settings/')['groups'] as $group) {
foreach ($group['fields'] as $field) {
$settings_definitions[$field['settinggroup']][$field['varname']] = $field;
}

View File

@@ -142,8 +142,6 @@ class UI
header("X-Content-Security-Policy: " . $csp_content);
header("X-WebKit-CSP: " . $csp_content);
header("X-XSS-Protection: 1; mode=block");
// Don't allow to load Froxlor in an iframe to prevent i.e. clickjacking
header("X-Frame-Options: DENY");

View File

@@ -92,7 +92,7 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
</daemon>
<!-- HTTP Lighttpd -->
<daemon name="lighttpd" title="LigHTTPd">
<daemon name="lighttpd" title="LigHTTPd (deprecated)">
<install><![CDATA[apt-get install lighttpd]]></install>
<file name="/etc/lighttpd/lighttpd.conf">
<content><![CDATA[

View File

@@ -92,7 +92,7 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
</daemon>
<!-- HTTP Lighttpd -->
<daemon name="lighttpd" title="LigHTTPd">
<daemon name="lighttpd" title="LigHTTPd (deprecated)">
<install><![CDATA[apt-get install lighttpd]]></install>
<file name="/etc/lighttpd/lighttpd.conf">
<content><![CDATA[

View File

@@ -91,7 +91,7 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
</daemon>
<!-- HTTP Lighttpd -->
<daemon name="lighttpd" title="LigHTTPd">
<daemon name="lighttpd" title="LigHTTPd (deprecated)">
<install><![CDATA[apt-get install lighttpd]]></install>
<file name="/etc/lighttpd/lighttpd.conf">
<content><![CDATA[

View File

@@ -100,7 +100,7 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
</daemon>
<!-- HTTP Lighttpd -->
<daemon name="lighttpd" title="LigHTTPd">
<daemon name="lighttpd" title="LigHTTPd (deprecated)">
<install><![CDATA[emerge www-servers/lighttpd]]></install>
<file name="/etc/lighttpd/lighttpd.conf">
<content><![CDATA[

View File

@@ -91,7 +91,7 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
</daemon>
<!-- HTTP Lighttpd -->
<daemon name="lighttpd" title="LigHTTPd">
<daemon name="lighttpd" title="LigHTTPd (deprecated)">
<install><![CDATA[apt-get install lighttpd]]></install>
<file name="/etc/lighttpd/lighttpd.conf">
<content><![CDATA[

View File

@@ -55,13 +55,16 @@ return [
'label' => lng('login.password'),
'type' => 'password',
'autocomplete' => 'off',
'mandatory' => true
],
'directory_password_suggestion' => [
'label' => lng('customer.generated_pwd'),
'type' => 'text',
'visible' => (Settings::Get('panel.password_regex') == ''),
'value' => Crypt::generatePassword()
'mandatory' => true,
'next_to' => [
'directory_password_suggestion' => [
'next_to_prefix' => lng('customer.generated_pwd') . ':',
'type' => 'text',
'visible' => (Settings::Get('panel.password_regex') == ''),
'value' => Crypt::generatePassword(),
'readonly' => true
]
]
],
'directory_authname' => [
'label' => lng('extras.htpasswdauthname'),

View File

@@ -49,13 +49,16 @@ return [
'directory_password' => [
'label' => lng('login.password'),
'type' => 'password',
'autocomplete' => 'off'
],
'directory_password_suggestion' => [
'label' => lng('customer.generated_pwd'),
'type' => 'text',
'visible' => (Settings::Get('panel.password_regex') == ''),
'value' => Crypt::generatePassword()
'autocomplete' => 'off',
'next_to' => [
'directory_password_suggestion' => [
'next_to_prefix' => lng('customer.generated_pwd') . ':',
'type' => 'text',
'visible' => (Settings::Get('panel.password_regex') == ''),
'value' => Crypt::generatePassword(),
'readonly' => true
]
]
],
'directory_authname' => [
'label' => lng('extras.htpasswdauthname'),

View File

@@ -46,14 +46,16 @@ return [
'label' => lng('login.password'),
'type' => 'password',
'autocomplete' => 'off',
'mandatory' => true
],
'mysql_password_suggestion' => [
'label' => lng('customer.generated_pwd'),
'type' => 'text',
'visible' => (Settings::Get('panel.password_regex') == ''),
'value' => Crypt::generatePassword(),
'readonly' => true
'mandatory' => true,
'next_to' => [
'mysql_password_suggestion' => [
'next_to_prefix' => lng('customer.generated_pwd') . ':',
'type' => 'text',
'visible' => (Settings::Get('panel.password_regex') == ''),
'value' => Crypt::generatePassword(),
'readonly' => true
]
]
],
'sendinfomail' => [
'label' => lng('customer.sendinfomail'),

View File

@@ -52,14 +52,16 @@ return [
'mysql_password' => [
'label' => lng('changepassword.new_password_ifnotempty'),
'type' => 'password',
'autocomplete' => 'off'
],
'mysql_password_suggestion' => [
'label' => lng('customer.generated_pwd'),
'type' => 'text',
'visible' => (Settings::Get('panel.password_regex') == ''),
'value' => Crypt::generatePassword(),
'readonly' => true
'autocomplete' => 'off',
'next_to' => [
'mysql_password_suggestion' => [
'next_to_prefix' => lng('customer.generated_pwd') . ':',
'type' => 'text',
'visible' => (Settings::Get('panel.password_regex') == ''),
'value' => Crypt::generatePassword(),
'readonly' => true
]
]
]
]
]

View File

@@ -44,7 +44,8 @@ return [
'cols' => 100,
'rows' => 15,
'value' => $result['ssl_cert_file'],
'placeholder' => lng('domain.ssl_certificate_placeholder')
'placeholder' => lng('domain.ssl_certificate_placeholder'),
'mandatory' => true
],
'ssl_key_file' => [
'label' => lng('admin.ipsandports.ssl_key_file_content'),
@@ -53,7 +54,8 @@ return [
'cols' => 100,
'rows' => 15,
'value' => $result['ssl_key_file'],
'placeholder' => lng('domain.ssl_key_placeholder')
'placeholder' => lng('domain.ssl_key_placeholder'),
'mandatory' => true
],
'ssl_cert_chainfile' => [
'label' => lng('admin.ipsandports.ssl_cert_chainfile_content'),

View File

@@ -50,10 +50,12 @@ if (!file_exists(dirname(__DIR__) . '/vendor/autoload.php')) {
require dirname(__DIR__) . '/vendor/autoload.php';
use Froxlor\CurrentUser;
use Froxlor\FileDir;
use Froxlor\Froxlor;
use Froxlor\FroxlorLogger;
use Froxlor\Http\RateLimiter;
use Froxlor\Idna\IdnaWrapper;
use Froxlor\Install\Update;
use Froxlor\Language;
use Froxlor\PhpHelper;
use Froxlor\Settings;
@@ -63,7 +65,6 @@ use Froxlor\UI\Linker;
use Froxlor\UI\Panel\UI;
use Froxlor\UI\Request;
use Froxlor\UI\Response;
use Froxlor\Install\Update;
// include MySQL-tabledefinitions
require Froxlor::getInstallDir() . '/lib/tables.inc.php';
@@ -110,6 +111,24 @@ if (!isset($sql) || !is_array($sql)) {
die();
}
/**
* Show nice note if requested domain is "unknown" to froxlor and thus is being lead to its vhost
*/
if ($_SERVER['HTTP_HOST'] != Settings::Get('system.hostname') &&
!filter_var($_SERVER['HTTP_HOST'], FILTER_VALIDATE_IP) && (
empty(Settings::Get('system.froxloraliases')) ||
(!empty(Settings::Get('system.froxloraliases')) && !in_array($_SERVER['HTTP_HOST'], array_map('trim', explode(',', Settings::Get('system.froxloraliases')))))
)) {
// not the froxlor system-hostname, show info page for domains not configured in froxlor
$unconfiguredPath = FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/templates/misc/unconfigured/index.html');
if (file_exists($unconfiguredPath)) {
echo file_get_contents($unconfiguredPath);
} else {
echo "This domain requires configuration via the froxlor server management panel, as it is currently not assigned to any customer.";
}
die();
}
// set error-handler
@set_error_handler([
'\\Froxlor\\PhpHelper',
@@ -182,9 +201,9 @@ if (@file_exists('templates/' . $theme . '/config.json')) {
// check for existence of variant in theme
if (is_array($_themeoptions) && (!array_key_exists('variants', $_themeoptions) || !array_key_exists(
$themevariant,
$_themeoptions['variants']
))) {
$themevariant,
$_themeoptions['variants']
))) {
$themevariant = "default";
}
@@ -242,7 +261,7 @@ if (CurrentUser::hasSession()) {
$log = FroxlorLogger::getInstanceOf($userinfo);
if ((CurrentUser::isAdmin() && AREA != 'admin') || (!CurrentUser::isAdmin() && AREA != 'customer')) {
// user tries to access an area not meant for him -> redirect to corresponding index
Response::redirectTo((CurrentUser::isAdmin() ? 'admin' : 'customer') . '_index.php', $params);
Response::redirectTo((CurrentUser::isAdmin() ? 'admin' : 'customer') . '_index.php');
exit();
}
}

View File

@@ -92,3 +92,10 @@ td.text-end {
background-color: transparent;
}
}
// Table
@include color-mode(light) {
.table {
--bs-table-bg: white;
}
}

View File

@@ -144,7 +144,7 @@
{% endmacro %}
{% macro plain(id, field) %}
<input type="text" readonly class="form-control-plaintext" id="{{ id }}" name="{{ id }}" value="{{ field.value|raw }}">
<input type="text" readonly class="form-control-plaintext" id="{{ id }}" name="{{ id }}" value="{{ field.value|raw|e }}">
{% if field.next_to is defined %}
{% for nid, nfield in field.next_to %}
{% if nfield.next_to_prefix is defined %}
@@ -159,9 +159,9 @@
{% if field.next_to is defined %}
<div class="input-group">
{% endif %}
<input type="{{ field.type }}" {% if field.visible is defined and field.visible == false %} disabled {% endif %} {% if field.type == 'number' and field.min is defined %} min="{{ field.min }}" {% endif %} {% if field.type == 'number' and field.max is defined %} max="{{ field.max }}" {% endif %} {% if field.type != 'number' and field.maxlength is defined %} maxlength="{{ field.maxlength }}" {% endif %} id="{{ id }}" name="{{ id }}" value="{{ field.value|raw }}" class="form-control {% if field.valid is defined and field.valid == false %}is-invalid{% endif %}" {% if field.mandatory is defined and field.mandatory %} required {% endif %} {% if field.readonly is defined and field.readonly %} readonly {% endif %} {% if field.autocomplete is defined %} autocomplete="{{ field.autocomplete }}" {% endif %} {% if field.placeholder is defined %} placeholder="{{ field.placeholder }}" {% endif %} {% if field.type == 'file' and field.accept is defined %} accept="{{ field.accept }}" {% endif %} {% if field.pattern is defined %} pattern="{{ field.pattern }}" {% endif %}/>
<input type="{{ field.type }}" {% if field.visible is defined and field.visible == false %} disabled {% endif %} {% if field.type == 'number' and field.min is defined %} min="{{ field.min }}" {% endif %} {% if field.type == 'number' and field.max is defined %} max="{{ field.max }}" {% endif %} {% if field.type != 'number' and field.maxlength is defined %} maxlength="{{ field.maxlength }}" {% endif %} id="{{ id }}" name="{{ id }}" value="{{ field.value|raw|e }}" class="form-control {% if field.valid is defined and field.valid == false %}is-invalid{% endif %}" {% if field.mandatory is defined and field.mandatory %} required {% endif %} {% if field.readonly is defined and field.readonly %} readonly {% endif %} {% if field.autocomplete is defined %} autocomplete="{{ field.autocomplete }}" {% endif %} {% if field.placeholder is defined %} placeholder="{{ field.placeholder }}" {% endif %} {% if field.type == 'file' and field.accept is defined %} accept="{{ field.accept }}" {% endif %} {% if field.pattern is defined %} pattern="{{ field.pattern }}" {% endif %}/>
{% if field.type == 'hidden' and field.display is defined %}
<input type="text" readonly class="form-control-plaintext" value="{{ field.display|raw }}">
<input type="text" readonly class="form-control-plaintext" value="{{ field.display|raw|e }}">
{% endif %}
{% if field.next_to is defined %}
{% for nid, nfield in field.next_to %}

View File

@@ -20,7 +20,7 @@
<td class="w-75" scope="row">{{ check.title }}</td>
<td class="col-auto text-end{% if check.result == 0 %} text-success{% endif %}">
<span class="d-none d-md-inline">{{ check.result_txt }}</span>
{% if check.result == 0 %}&nbsp;<i class="fa-solid fa-check-circle" {% elseif check.result == 2 %}<span class="d-md-none">&nbsp;???</span>{% elseif check.result == 1 %}<span class="d-md-none">&nbsp;!!!</span>
{% if check.result == 0 %}&nbsp;<i class="fa-solid fa-check-circle"></i>{% elseif check.result == 2 %}<span class="d-md-none">&nbsp;???</span>{% elseif check.result == 1 %}<span class="d-md-none">&nbsp;!!!</span>
{% endif %}
</td>
</tr>

View File

@@ -41,7 +41,7 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="icon">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" />
</svg>
<span>Please ask your provider/hoster if you think this is not correct</span>
<span>Please ask your provider/hoster if you have any questions.</span>
</li>
</ul>
</main>

View File

@@ -0,0 +1,55 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex, nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>froxlor - Deactivated page</title>
<style>
:root{--primary:#1872a2;--fonts:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}
body{display:flex;flex-direction:column;background:#f8f9fa;color:#4b5563;align-items:center;justify-content:center;font-family:var(--fonts)}
main{background:#fff;margin:10% auto 12px;max-width:540px;padding:2rem;box-shadow:4px 8px 16px 0 rgba(0,0,0,.07);border-radius:.375rem}
main h2{margin:0}
main p{margin-bottom:1.5rem}
main p:last-child{margin-bottom:0}
main ul{list-style:none;margin-left:-40px}
main li{display:flex;align-items:center;margin-bottom:1rem}
main .icon{min-width:24px;width:24px;stroke:var(--primary);margin-right:.75rem}
code{background:#eee;padding:.1rem .25rem;border-radius:4px;color:rgba(0,0,0,.75)}
hr{margin:2rem 0;border:none;border-bottom:solid 1px rgba(0,0,0,.1)}
a,a:active,a:visited{color:var(--primary);text-decoration:none}
a:hover{text-decoration:underline}
footer{display:flex;align-items:center;margin-top:.5rem}
footer .logo{margin-right:.35rem}
@media (prefers-color-scheme: dark) {
:root{--primary:#29a2d6}
body{background:#212529;color:#f8f9fa}
main{background:#343a40}
hr{border-color:rgba(0,0,0,.2)}
}
</style>
</head>
<body>
<main>
<h2>Domain not configured</h2>
<p>
This domain requires configuration via the froxlor server management panel, as it is currently not assigned to any customer.
</p>
<ul>
<li>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="icon">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" />
</svg>
<span>Please ask your provider/hoster if you have any questions.</span>
</li>
</ul>
</main>
<footer>
<img class="logo" src="data:image/png;base64,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" alt="froxlor"/>
<small>&copy; 2009-<span id="year"></span> by <a href="https://froxlor.org" rel="external">the froxlor team</a></small>
</footer>
<script>
document.getElementById("year").innerHTML = new Date().getFullYear();
</script>
</body>
</html>