Compare commits
13 Commits
2.1.0-beta
...
2.1.0-rc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1debe9d939 | ||
|
|
3d2e81b457 | ||
|
|
ac759cd9a4 | ||
|
|
05c77929e4 | ||
|
|
cefd9226bd | ||
|
|
762f295d3d | ||
|
|
d3e6063027 | ||
|
|
f18c14e119 | ||
|
|
77bcd10729 | ||
|
|
6ee990af0a | ||
|
|
a3fe37b69b | ||
|
|
56388ede54 | ||
|
|
b98035bf3a |
10
README.md
10
README.md
@@ -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
|
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
|
### Forum
|
||||||
|
|
||||||
The community is located on https://forum.froxlor.org/
|
The community is located on https://forum.froxlor.org/
|
||||||
|
|
||||||
### Wiki
|
### Documentation
|
||||||
|
|
||||||
More documentation may be found in the froxlor - documentation:
|
The documentation may be found at https://docs.froxlor.org/
|
||||||
https://docs.froxlor.org/
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ With that, good luck hacking us ;)
|
|||||||
|
|
||||||
### Vulnerabilities we accept
|
### 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
|
## Non-Qualifying Vulnerabilities
|
||||||
|
|
||||||
@@ -45,4 +45,4 @@ Only reproducable issues on a default/clean setup from the latest stable release
|
|||||||
|
|
||||||
## Reporting a Vulnerability
|
## 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).
|
||||||
|
|||||||
@@ -679,7 +679,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.0-beta2'),
|
('system', 'update_notify_last', '2.1.0-rc1'),
|
||||||
('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),
|
||||||
@@ -727,7 +727,7 @@ 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.0-beta2'),
|
('panel', 'version', '2.1.0-rc1'),
|
||||||
('panel', 'db_version', '202305240');
|
('panel', 'db_version', '202305240');
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -103,3 +103,8 @@ if (Froxlor::isFroxlorVersion('2.1.0-beta1')) {
|
|||||||
|
|
||||||
Froxlor::updateToVersion('2.1.0-beta2');
|
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');
|
||||||
|
}
|
||||||
|
|||||||
@@ -176,8 +176,9 @@ class IpsAndPorts extends ApiCommand implements ResourceEntity
|
|||||||
|
|
||||||
if ((int)Settings::Get('system.use_ssl') == 1) {
|
if ((int)Settings::Get('system.use_ssl') == 1) {
|
||||||
$ssl = (bool)$this->getBoolParam('ssl', true, 0);
|
$ssl = (bool)$this->getBoolParam('ssl', true, 0);
|
||||||
$ssl_cert_file = Validate::validate($this->getParam('ssl_cert_file', !$ssl, ''), 'ssl_cert_file', '', '', [], true);
|
$cert_optional = !($ssl && empty(Settings::Get('system.ssl_cert_file')));
|
||||||
$ssl_key_file = Validate::validate($this->getParam('ssl_key_file', !$ssl, ''), 'ssl_key_file', '', '', [], true);
|
$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_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);
|
$ssl_cert_chainfile = Validate::validate($this->getParam('ssl_cert_chainfile', true, ''), 'ssl_cert_chainfile', '', '', [], true);
|
||||||
$sslss = $this->getParam('ssl_specialsettings', 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) {
|
if ((int)Settings::Get('system.use_ssl') == 1) {
|
||||||
$ssl = (bool)$this->getBoolParam('ssl', true, $result['ssl']);
|
$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);
|
$cert_optional = !($ssl && empty(Settings::Get('system.ssl_cert_file')));
|
||||||
$ssl_key_file = Validate::validate($this->getParam('ssl_key_file', !$ssl, $result['ssl_key_file']), 'ssl_key_file', '', '', [], true);
|
$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_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);
|
$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']);
|
$sslss = $this->getParam('ssl_specialsettings', true, $result['ssl_specialsettings']);
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ final class UpdateCommand extends CliCommand
|
|||||||
|
|
||||||
// database update only
|
// database update only
|
||||||
if ($input->getOption('database')) {
|
if ($input->getOption('database')) {
|
||||||
$result = $this->validateRequirements($input, $output, true);
|
$result = $this->validateRequirements($output, true);
|
||||||
if ($result == self::SUCCESS) {
|
if ($result == self::SUCCESS) {
|
||||||
if (Froxlor::hasUpdates() || Froxlor::hasDbUpdates()) {
|
if (Froxlor::hasUpdates() || Froxlor::hasDbUpdates()) {
|
||||||
$output->writeln('<info>' . lng('updates.dbupdate_required') . '</>');
|
$output->writeln('<info>' . lng('updates.dbupdate_required') . '</>');
|
||||||
@@ -77,7 +77,7 @@ final class UpdateCommand extends CliCommand
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->validateRequirements($input, $output);
|
$result = $this->validateRequirements($output);
|
||||||
|
|
||||||
if ($result != self::SUCCESS) {
|
if ($result != self::SUCCESS) {
|
||||||
// requirements failed, exit
|
// requirements failed, exit
|
||||||
|
|||||||
@@ -515,13 +515,7 @@ class Apache extends HttpConfigBase
|
|||||||
*/
|
*/
|
||||||
private function createStandardDirectoryEntry()
|
private function createStandardDirectoryEntry()
|
||||||
{
|
{
|
||||||
$vhosts_folder = '';
|
$vhosts_filename = $this->getCustomVhostFilename('05_froxlor_dirfix_nofcgid.conf');
|
||||||
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');
|
|
||||||
|
|
||||||
if (!isset($this->virtualhosts_data[$vhosts_filename])) {
|
if (!isset($this->virtualhosts_data[$vhosts_filename])) {
|
||||||
$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";
|
$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) {
|
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";
|
$this->virtualhosts_data[$ocsp_cache_filename] = 'SSLStaplingCache ' . Settings::Get('system.apache24_ocsp_cache_path') . "\n";
|
||||||
} else {
|
} else {
|
||||||
@@ -562,14 +556,7 @@ class Apache extends HttpConfigBase
|
|||||||
private function createStandardErrorHandler()
|
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') != '')) {
|
if (Settings::Get('defaultwebsrverrhandler.enabled') == '1' && (Settings::Get('defaultwebsrverrhandler.err401') != '' || Settings::Get('defaultwebsrverrhandler.err403') != '' || Settings::Get('defaultwebsrverrhandler.err404') != '' || Settings::Get('defaultwebsrverrhandler.err500') != '')) {
|
||||||
$vhosts_folder = '';
|
$vhosts_filename = $this->getCustomVhostFilename('05_froxlor_default_errorhandler.conf');
|
||||||
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');
|
|
||||||
|
|
||||||
if (!isset($this->virtualhosts_data[$vhosts_filename])) {
|
if (!isset($this->virtualhosts_data[$vhosts_filename])) {
|
||||||
$this->virtualhosts_data[$vhosts_filename] = '';
|
$this->virtualhosts_data[$vhosts_filename] = '';
|
||||||
|
|||||||
@@ -202,4 +202,13 @@ class HttpConfigBase
|
|||||||
}
|
}
|
||||||
return FileDir::makeCorrectFile(Settings::Get('system.apacheconf_vhost') . '/' . $filename);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1161,14 +1161,7 @@ class Nginx extends HttpConfigBase
|
|||||||
private function createStandardErrorHandler()
|
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') != '')) {
|
if (Settings::Get('defaultwebsrverrhandler.enabled') == '1' && (Settings::Get('defaultwebsrverrhandler.err401') != '' || Settings::Get('defaultwebsrverrhandler.err403') != '' || Settings::Get('defaultwebsrverrhandler.err404') != '' || Settings::Get('defaultwebsrverrhandler.err500') != '')) {
|
||||||
$vhosts_folder = '';
|
$vhosts_filename = $this->getCustomVhostFilename('05_froxlor_default_errorhandler.conf');
|
||||||
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');
|
|
||||||
|
|
||||||
if (!isset($this->nginx_data[$vhosts_filename])) {
|
if (!isset($this->nginx_data[$vhosts_filename])) {
|
||||||
$this->nginx_data[$vhosts_filename] = '';
|
$this->nginx_data[$vhosts_filename] = '';
|
||||||
|
|||||||
@@ -320,12 +320,15 @@ class Domain
|
|||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function triggerLetsEncryptCSRForAliasDestinationDomain(
|
public static function triggerLetsEncryptCSRForAliasDestinationDomain(
|
||||||
int $aliasDestinationDomainID,
|
int $aliasDestinationDomainID,
|
||||||
FroxlorLogger $log
|
FroxlorLogger $log
|
||||||
) {
|
) {
|
||||||
if ($aliasDestinationDomainID > 0) {
|
if ($aliasDestinationDomainID > 0) {
|
||||||
$log->logAction(FroxlorLogger::ADM_ACTION, LOG_INFO,
|
$log->logAction(
|
||||||
"LetsEncrypt CSR triggered for domain ID " . $aliasDestinationDomainID);
|
FroxlorLogger::ADM_ACTION,
|
||||||
|
LOG_INFO,
|
||||||
|
"LetsEncrypt CSR triggered for domain ID " . $aliasDestinationDomainID
|
||||||
|
);
|
||||||
$upd_stmt = Database::prepare("UPDATE
|
$upd_stmt = Database::prepare("UPDATE
|
||||||
`" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
|
`" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "`
|
||||||
SET
|
SET
|
||||||
@@ -349,15 +352,20 @@ class Domain
|
|||||||
$acmesh = AcmeSh::getAcmeSh();
|
$acmesh = AcmeSh::getAcmeSh();
|
||||||
if (file_exists($acmesh)) {
|
if (file_exists($acmesh)) {
|
||||||
$certificate_folder = AcmeSh::getWorkingDirFromEnv($domainname);
|
$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;
|
$params = " --remove -d " . $domainname;
|
||||||
if (Settings::Get('system.leecc') > 0) {
|
if (file_exists($certificate_ecc_folder)) {
|
||||||
$params .= " --ecc";
|
$params .= " --ecc";
|
||||||
}
|
}
|
||||||
// run remove command
|
// run remove command
|
||||||
FileDir::safe_exec($acmesh . $params);
|
FileDir::safe_exec($acmesh . $params);
|
||||||
// remove certificates directory
|
// 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;
|
return true;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ final class Froxlor
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Main version variable
|
// Main version variable
|
||||||
const VERSION = '2.1.0-beta2';
|
const VERSION = '2.1.0-rc1';
|
||||||
|
|
||||||
// Database version (YYYYMMDDC where C is a daily counter)
|
// Database version (YYYYMMDDC where C is a daily counter)
|
||||||
const DBVERSION = '202305240';
|
const DBVERSION = '202305240';
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ class Update
|
|||||||
self::$update_tasks[self::$task_counter]['result'] = 1;
|
self::$update_tasks[self::$task_counter]['result'] = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
self::$update_tasks[self::$task_counter]['result'] = -1;
|
self::$update_tasks[self::$task_counter]['result'] = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class SImExporter
|
|||||||
public static function export()
|
public static function export()
|
||||||
{
|
{
|
||||||
$settings_definitions = [];
|
$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) {
|
foreach ($group['fields'] as $field) {
|
||||||
$settings_definitions[$field['settinggroup']][$field['varname']] = $field;
|
$settings_definitions[$field['settinggroup']][$field['varname']] = $field;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,8 +142,6 @@ class UI
|
|||||||
header("X-Content-Security-Policy: " . $csp_content);
|
header("X-Content-Security-Policy: " . $csp_content);
|
||||||
header("X-WebKit-CSP: " . $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
|
// Don't allow to load Froxlor in an iframe to prevent i.e. clickjacking
|
||||||
header("X-Frame-Options: DENY");
|
header("X-Frame-Options: DENY");
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
|
|||||||
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
|
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
|
||||||
</daemon>
|
</daemon>
|
||||||
<!-- HTTP Lighttpd -->
|
<!-- HTTP Lighttpd -->
|
||||||
<daemon name="lighttpd" title="LigHTTPd">
|
<daemon name="lighttpd" title="LigHTTPd (deprecated)">
|
||||||
<install><![CDATA[apt-get install lighttpd]]></install>
|
<install><![CDATA[apt-get install lighttpd]]></install>
|
||||||
<file name="/etc/lighttpd/lighttpd.conf">
|
<file name="/etc/lighttpd/lighttpd.conf">
|
||||||
<content><![CDATA[
|
<content><![CDATA[
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
|
|||||||
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
|
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
|
||||||
</daemon>
|
</daemon>
|
||||||
<!-- HTTP Lighttpd -->
|
<!-- HTTP Lighttpd -->
|
||||||
<daemon name="lighttpd" title="LigHTTPd">
|
<daemon name="lighttpd" title="LigHTTPd (deprecated)">
|
||||||
<install><![CDATA[apt-get install lighttpd]]></install>
|
<install><![CDATA[apt-get install lighttpd]]></install>
|
||||||
<file name="/etc/lighttpd/lighttpd.conf">
|
<file name="/etc/lighttpd/lighttpd.conf">
|
||||||
<content><![CDATA[
|
<content><![CDATA[
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
|
|||||||
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
|
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
|
||||||
</daemon>
|
</daemon>
|
||||||
<!-- HTTP Lighttpd -->
|
<!-- HTTP Lighttpd -->
|
||||||
<daemon name="lighttpd" title="LigHTTPd">
|
<daemon name="lighttpd" title="LigHTTPd (deprecated)">
|
||||||
<install><![CDATA[apt-get install lighttpd]]></install>
|
<install><![CDATA[apt-get install lighttpd]]></install>
|
||||||
<file name="/etc/lighttpd/lighttpd.conf">
|
<file name="/etc/lighttpd/lighttpd.conf">
|
||||||
<content><![CDATA[
|
<content><![CDATA[
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
|
|||||||
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
|
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
|
||||||
</daemon>
|
</daemon>
|
||||||
<!-- HTTP Lighttpd -->
|
<!-- HTTP Lighttpd -->
|
||||||
<daemon name="lighttpd" title="LigHTTPd">
|
<daemon name="lighttpd" title="LigHTTPd (deprecated)">
|
||||||
<install><![CDATA[emerge www-servers/lighttpd]]></install>
|
<install><![CDATA[emerge www-servers/lighttpd]]></install>
|
||||||
<file name="/etc/lighttpd/lighttpd.conf">
|
<file name="/etc/lighttpd/lighttpd.conf">
|
||||||
<content><![CDATA[
|
<content><![CDATA[
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ Alias "/.well-known/acme-challenge" "{{settings.system.letsencryptchallengepath}
|
|||||||
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
|
<command><![CDATA[{{settings.system.apachereload_command}}]]></command>
|
||||||
</daemon>
|
</daemon>
|
||||||
<!-- HTTP Lighttpd -->
|
<!-- HTTP Lighttpd -->
|
||||||
<daemon name="lighttpd" title="LigHTTPd">
|
<daemon name="lighttpd" title="LigHTTPd (deprecated)">
|
||||||
<install><![CDATA[apt-get install lighttpd]]></install>
|
<install><![CDATA[apt-get install lighttpd]]></install>
|
||||||
<file name="/etc/lighttpd/lighttpd.conf">
|
<file name="/etc/lighttpd/lighttpd.conf">
|
||||||
<content><![CDATA[
|
<content><![CDATA[
|
||||||
|
|||||||
@@ -55,13 +55,16 @@ return [
|
|||||||
'label' => lng('login.password'),
|
'label' => lng('login.password'),
|
||||||
'type' => 'password',
|
'type' => 'password',
|
||||||
'autocomplete' => 'off',
|
'autocomplete' => 'off',
|
||||||
'mandatory' => true
|
'mandatory' => true,
|
||||||
],
|
'next_to' => [
|
||||||
'directory_password_suggestion' => [
|
'directory_password_suggestion' => [
|
||||||
'label' => lng('customer.generated_pwd'),
|
'next_to_prefix' => lng('customer.generated_pwd') . ':',
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'visible' => (Settings::Get('panel.password_regex') == ''),
|
'visible' => (Settings::Get('panel.password_regex') == ''),
|
||||||
'value' => Crypt::generatePassword()
|
'value' => Crypt::generatePassword(),
|
||||||
|
'readonly' => true
|
||||||
|
]
|
||||||
|
]
|
||||||
],
|
],
|
||||||
'directory_authname' => [
|
'directory_authname' => [
|
||||||
'label' => lng('extras.htpasswdauthname'),
|
'label' => lng('extras.htpasswdauthname'),
|
||||||
|
|||||||
@@ -49,13 +49,16 @@ return [
|
|||||||
'directory_password' => [
|
'directory_password' => [
|
||||||
'label' => lng('login.password'),
|
'label' => lng('login.password'),
|
||||||
'type' => 'password',
|
'type' => 'password',
|
||||||
'autocomplete' => 'off'
|
'autocomplete' => 'off',
|
||||||
],
|
'next_to' => [
|
||||||
'directory_password_suggestion' => [
|
'directory_password_suggestion' => [
|
||||||
'label' => lng('customer.generated_pwd'),
|
'next_to_prefix' => lng('customer.generated_pwd') . ':',
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'visible' => (Settings::Get('panel.password_regex') == ''),
|
'visible' => (Settings::Get('panel.password_regex') == ''),
|
||||||
'value' => Crypt::generatePassword()
|
'value' => Crypt::generatePassword(),
|
||||||
|
'readonly' => true
|
||||||
|
]
|
||||||
|
]
|
||||||
],
|
],
|
||||||
'directory_authname' => [
|
'directory_authname' => [
|
||||||
'label' => lng('extras.htpasswdauthname'),
|
'label' => lng('extras.htpasswdauthname'),
|
||||||
|
|||||||
@@ -46,14 +46,16 @@ return [
|
|||||||
'label' => lng('login.password'),
|
'label' => lng('login.password'),
|
||||||
'type' => 'password',
|
'type' => 'password',
|
||||||
'autocomplete' => 'off',
|
'autocomplete' => 'off',
|
||||||
'mandatory' => true
|
'mandatory' => true,
|
||||||
],
|
'next_to' => [
|
||||||
'mysql_password_suggestion' => [
|
'mysql_password_suggestion' => [
|
||||||
'label' => lng('customer.generated_pwd'),
|
'next_to_prefix' => lng('customer.generated_pwd') . ':',
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'visible' => (Settings::Get('panel.password_regex') == ''),
|
'visible' => (Settings::Get('panel.password_regex') == ''),
|
||||||
'value' => Crypt::generatePassword(),
|
'value' => Crypt::generatePassword(),
|
||||||
'readonly' => true
|
'readonly' => true
|
||||||
|
]
|
||||||
|
]
|
||||||
],
|
],
|
||||||
'sendinfomail' => [
|
'sendinfomail' => [
|
||||||
'label' => lng('customer.sendinfomail'),
|
'label' => lng('customer.sendinfomail'),
|
||||||
|
|||||||
@@ -52,14 +52,16 @@ return [
|
|||||||
'mysql_password' => [
|
'mysql_password' => [
|
||||||
'label' => lng('changepassword.new_password_ifnotempty'),
|
'label' => lng('changepassword.new_password_ifnotempty'),
|
||||||
'type' => 'password',
|
'type' => 'password',
|
||||||
'autocomplete' => 'off'
|
'autocomplete' => 'off',
|
||||||
],
|
'next_to' => [
|
||||||
'mysql_password_suggestion' => [
|
'mysql_password_suggestion' => [
|
||||||
'label' => lng('customer.generated_pwd'),
|
'next_to_prefix' => lng('customer.generated_pwd') . ':',
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'visible' => (Settings::Get('panel.password_regex') == ''),
|
'visible' => (Settings::Get('panel.password_regex') == ''),
|
||||||
'value' => Crypt::generatePassword(),
|
'value' => Crypt::generatePassword(),
|
||||||
'readonly' => true
|
'readonly' => true
|
||||||
|
]
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ return [
|
|||||||
'cols' => 100,
|
'cols' => 100,
|
||||||
'rows' => 15,
|
'rows' => 15,
|
||||||
'value' => $result['ssl_cert_file'],
|
'value' => $result['ssl_cert_file'],
|
||||||
'placeholder' => lng('domain.ssl_certificate_placeholder')
|
'placeholder' => lng('domain.ssl_certificate_placeholder'),
|
||||||
|
'mandatory' => true
|
||||||
],
|
],
|
||||||
'ssl_key_file' => [
|
'ssl_key_file' => [
|
||||||
'label' => lng('admin.ipsandports.ssl_key_file_content'),
|
'label' => lng('admin.ipsandports.ssl_key_file_content'),
|
||||||
@@ -53,7 +54,8 @@ return [
|
|||||||
'cols' => 100,
|
'cols' => 100,
|
||||||
'rows' => 15,
|
'rows' => 15,
|
||||||
'value' => $result['ssl_key_file'],
|
'value' => $result['ssl_key_file'],
|
||||||
'placeholder' => lng('domain.ssl_key_placeholder')
|
'placeholder' => lng('domain.ssl_key_placeholder'),
|
||||||
|
'mandatory' => true
|
||||||
],
|
],
|
||||||
'ssl_cert_chainfile' => [
|
'ssl_cert_chainfile' => [
|
||||||
'label' => lng('admin.ipsandports.ssl_cert_chainfile_content'),
|
'label' => lng('admin.ipsandports.ssl_cert_chainfile_content'),
|
||||||
|
|||||||
29
lib/init.php
29
lib/init.php
@@ -50,10 +50,12 @@ if (!file_exists(dirname(__DIR__) . '/vendor/autoload.php')) {
|
|||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
use Froxlor\CurrentUser;
|
use Froxlor\CurrentUser;
|
||||||
|
use Froxlor\FileDir;
|
||||||
use Froxlor\Froxlor;
|
use Froxlor\Froxlor;
|
||||||
use Froxlor\FroxlorLogger;
|
use Froxlor\FroxlorLogger;
|
||||||
use Froxlor\Http\RateLimiter;
|
use Froxlor\Http\RateLimiter;
|
||||||
use Froxlor\Idna\IdnaWrapper;
|
use Froxlor\Idna\IdnaWrapper;
|
||||||
|
use Froxlor\Install\Update;
|
||||||
use Froxlor\Language;
|
use Froxlor\Language;
|
||||||
use Froxlor\PhpHelper;
|
use Froxlor\PhpHelper;
|
||||||
use Froxlor\Settings;
|
use Froxlor\Settings;
|
||||||
@@ -63,7 +65,6 @@ use Froxlor\UI\Linker;
|
|||||||
use Froxlor\UI\Panel\UI;
|
use Froxlor\UI\Panel\UI;
|
||||||
use Froxlor\UI\Request;
|
use Froxlor\UI\Request;
|
||||||
use Froxlor\UI\Response;
|
use Froxlor\UI\Response;
|
||||||
use Froxlor\Install\Update;
|
|
||||||
|
|
||||||
// include MySQL-tabledefinitions
|
// include MySQL-tabledefinitions
|
||||||
require Froxlor::getInstallDir() . '/lib/tables.inc.php';
|
require Froxlor::getInstallDir() . '/lib/tables.inc.php';
|
||||||
@@ -110,6 +111,24 @@ if (!isset($sql) || !is_array($sql)) {
|
|||||||
die();
|
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
|
||||||
@set_error_handler([
|
@set_error_handler([
|
||||||
'\\Froxlor\\PhpHelper',
|
'\\Froxlor\\PhpHelper',
|
||||||
@@ -182,9 +201,9 @@ if (@file_exists('templates/' . $theme . '/config.json')) {
|
|||||||
|
|
||||||
// check for existence of variant in theme
|
// check for existence of variant in theme
|
||||||
if (is_array($_themeoptions) && (!array_key_exists('variants', $_themeoptions) || !array_key_exists(
|
if (is_array($_themeoptions) && (!array_key_exists('variants', $_themeoptions) || !array_key_exists(
|
||||||
$themevariant,
|
$themevariant,
|
||||||
$_themeoptions['variants']
|
$_themeoptions['variants']
|
||||||
))) {
|
))) {
|
||||||
$themevariant = "default";
|
$themevariant = "default";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +261,7 @@ if (CurrentUser::hasSession()) {
|
|||||||
$log = FroxlorLogger::getInstanceOf($userinfo);
|
$log = FroxlorLogger::getInstanceOf($userinfo);
|
||||||
if ((CurrentUser::isAdmin() && AREA != 'admin') || (!CurrentUser::isAdmin() && AREA != 'customer')) {
|
if ((CurrentUser::isAdmin() && AREA != 'admin') || (!CurrentUser::isAdmin() && AREA != 'customer')) {
|
||||||
// user tries to access an area not meant for him -> redirect to corresponding index
|
// 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();
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,3 +92,10 @@ td.text-end {
|
|||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Table
|
||||||
|
@include color-mode(light) {
|
||||||
|
.table {
|
||||||
|
--bs-table-bg: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@
|
|||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro plain(id, field) %}
|
{% 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 %}
|
{% if field.next_to is defined %}
|
||||||
{% for nid, nfield in field.next_to %}
|
{% for nid, nfield in field.next_to %}
|
||||||
{% if nfield.next_to_prefix is defined %}
|
{% if nfield.next_to_prefix is defined %}
|
||||||
@@ -159,9 +159,9 @@
|
|||||||
{% if field.next_to is defined %}
|
{% if field.next_to is defined %}
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
{% endif %}
|
{% 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 %}
|
{% 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 %}
|
{% endif %}
|
||||||
{% if field.next_to is defined %}
|
{% if field.next_to is defined %}
|
||||||
{% for nid, nfield in field.next_to %}
|
{% for nid, nfield in field.next_to %}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<td class="w-75" scope="row">{{ check.title }}</td>
|
<td class="w-75" scope="row">{{ check.title }}</td>
|
||||||
<td class="col-auto text-end{% if check.result == 0 %} text-success{% endif %}">
|
<td class="col-auto text-end{% if check.result == 0 %} text-success{% endif %}">
|
||||||
<span class="d-none d-md-inline">{{ check.result_txt }}</span>
|
<span class="d-none d-md-inline">{{ check.result_txt }}</span>
|
||||||
{% if check.result == 0 %} <i class="fa-solid fa-check-circle" {% elseif check.result == 2 %}<span class="d-md-none"> ???</span>{% elseif check.result == 1 %}<span class="d-md-none"> !!!</span>
|
{% if check.result == 0 %} <i class="fa-solid fa-check-circle"></i>{% elseif check.result == 2 %}<span class="d-md-none"> ???</span>{% elseif check.result == 1 %}<span class="d-md-none"> !!!</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -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">
|
<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" />
|
<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>
|
</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>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
55
templates/misc/unconfigured/index.html
Normal file
55
templates/misc/unconfigured/index.html
Normal 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>© 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>
|
||||||
Reference in New Issue
Block a user