Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
775d50306c | ||
|
|
3821144c3b | ||
|
|
a1da70c221 | ||
|
|
bb2db0fed0 | ||
|
|
9680f24640 | ||
|
|
c732fbd81b | ||
|
|
7980b8d14d | ||
|
|
13e88f5b47 | ||
|
|
031596301b | ||
|
|
b34ab45746 | ||
|
|
dbf83c6f24 | ||
|
|
4cb974839c | ||
|
|
1fa714ef2c |
2
.github/workflows/build-mariadb.yml
vendored
2
.github/workflows/build-mariadb.yml
vendored
@@ -53,7 +53,7 @@ jobs:
|
||||
name: Create nightly/testing tarball
|
||||
runs-on: ubuntu-latest
|
||||
needs: froxlor
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -10,7 +10,8 @@ With that, good luck hacking us ;)
|
||||
|
||||
## Supported versions
|
||||
|
||||
- ️✅ **2.1.x** (`main` git-branch)
|
||||
- ️✅ **2.2.x** (`main` git-branch)
|
||||
- ️✅ **2.1.x** (`v2.1` git-branch)
|
||||
- ❌ 2.0.x (`2.0.x`-tags)
|
||||
- ❌ 0.10.x (`0.10.x`-tags)
|
||||
- ❌ other git-branches
|
||||
|
||||
@@ -726,7 +726,7 @@ opcache.validate_timestamps'),
|
||||
('panel', 'logo_overridecustom', '0'),
|
||||
('panel', 'settings_mode', '0'),
|
||||
('panel', 'menu_collapsed', '1'),
|
||||
('panel', 'version', '2.1.4'),
|
||||
('panel', 'version', '2.1.6'),
|
||||
('panel', 'db_version', '202312120');
|
||||
|
||||
|
||||
|
||||
@@ -279,3 +279,13 @@ if (Froxlor::isFroxlorVersion('2.1.3')) {
|
||||
Update::showUpdateStep("Updating from 2.1.3 to 2.1.4", false);
|
||||
Froxlor::updateToVersion('2.1.4');
|
||||
}
|
||||
|
||||
if (Froxlor::isFroxlorVersion('2.1.4')) {
|
||||
Update::showUpdateStep("Updating from 2.1.4 to 2.1.5", false);
|
||||
Froxlor::updateToVersion('2.1.5');
|
||||
}
|
||||
|
||||
if (Froxlor::isFroxlorVersion('2.1.5')) {
|
||||
Update::showUpdateStep("Updating from 2.1.5 to 2.1.6", false);
|
||||
Froxlor::updateToVersion('2.1.6');
|
||||
}
|
||||
|
||||
@@ -400,8 +400,11 @@ class Customers extends ApiCommand implements ResourceEntity
|
||||
$allowed_phpconfigs = array_map('intval', $allowed_phpconfigs);
|
||||
|
||||
if (empty($allowed_phpconfigs) && $phpenabled == 1) {
|
||||
// only required if not using mod_php
|
||||
if ((int)Settings::Get('system.mod_fcgid') == 1 || (int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
Response::standardError('customerphpenabledbutnoconfig', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
$allowed_mysqlserver = array();
|
||||
if (! empty($p_allowed_mysqlserver) && is_array($p_allowed_mysqlserver)) {
|
||||
@@ -1114,8 +1117,11 @@ class Customers extends ApiCommand implements ResourceEntity
|
||||
$allowed_phpconfigs = array_map('intval', $allowed_phpconfigs);
|
||||
}
|
||||
if (empty($allowed_phpconfigs) && $phpenabled == 1) {
|
||||
// only required if not using mod_php
|
||||
if ((int)Settings::Get('system.mod_fcgid') == 1 || (int)Settings::Get('phpfpm.enabled') == 1) {
|
||||
Response::standardError('customerphpenabledbutnoconfig', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// add permission for allowed mysql usage if customer was not allowed to use mysql prior
|
||||
if ($result['mysqls'] == 0 && ($mysqls == -1 || $mysqls > 0)) {
|
||||
|
||||
@@ -157,10 +157,10 @@ class EmailAccounts extends ApiCommand implements ResourceEntity
|
||||
|
||||
// prefix hash-algo
|
||||
switch (Settings::Get('system.passwordcryptfunc')) {
|
||||
case PASSWORD_ARGON2I:
|
||||
case 'argon2i':
|
||||
$cpPrefix = '{ARGON2I}';
|
||||
break;
|
||||
case PASSWORD_ARGON2ID:
|
||||
case 'argon2id':
|
||||
$cpPrefix = '{ARGON2ID}';
|
||||
break;
|
||||
default:
|
||||
@@ -404,10 +404,10 @@ class EmailAccounts extends ApiCommand implements ResourceEntity
|
||||
$password = Crypt::validatePassword($password, true);
|
||||
// prefix hash-algo
|
||||
switch (Settings::Get('system.passwordcryptfunc')) {
|
||||
case PASSWORD_ARGON2I:
|
||||
case 'argon2i':
|
||||
$cpPrefix = '{ARGON2I}';
|
||||
break;
|
||||
case PASSWORD_ARGON2ID:
|
||||
case 'argon2id':
|
||||
$cpPrefix = '{ARGON2ID}';
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -110,7 +110,7 @@ final class UpdateCommand extends CliCommand
|
||||
$newversionavail = true;
|
||||
$output->writeln('<comment>' . $text . '</>');
|
||||
$result = self::SUCCESS;
|
||||
} else if ($aucheck < 0 || $aucheck > 1) {
|
||||
} elseif ($aucheck < 0 || $aucheck > 1) {
|
||||
if ($input->getOption('integer-return')) {
|
||||
$output->write(-1);
|
||||
return self::INVALID;
|
||||
|
||||
@@ -55,12 +55,10 @@ class Bind extends DnsBase
|
||||
$domains = $this->getDomainList();
|
||||
|
||||
if (empty($domains)) {
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'No domains found for nameserver-config, skipping...');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'No domains found for nameserver-config, not creating any zones...');
|
||||
$this->bindconf_file = '';
|
||||
} else {
|
||||
$this->bindconf_file = '# ' . Settings::Get('system.bindconf_directory') . 'froxlor_bind.conf' . "\n" . '# Created ' . date('d.m.Y H:i') . "\n" . '# Do NOT manually edit this file, all changes will be deleted after the next domain change at the panel.' . "\n\n";
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
if ($domain['is_child']) {
|
||||
// domains that are subdomains to other main domains are handled by recursion within walkDomainList()
|
||||
@@ -68,6 +66,7 @@ class Bind extends DnsBase
|
||||
}
|
||||
$this->walkDomainList($domain, $domains);
|
||||
}
|
||||
}
|
||||
|
||||
$bindconf_file_handler = fopen(FileDir::makeCorrectFile(Settings::Get('system.bindconf_directory') . '/froxlor_bind.conf'), 'w');
|
||||
fwrite($bindconf_file_handler, $this->bindconf_file);
|
||||
|
||||
@@ -45,10 +45,8 @@ class PowerDNS extends DnsBase
|
||||
$this->clearZoneTables($domains);
|
||||
|
||||
if (empty($domains)) {
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'No domains found for nameserver-config, skipping...');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'No domains found for nameserver-config, not creating any zones...');
|
||||
} else {
|
||||
foreach ($domains as $domain) {
|
||||
if ($domain['is_child']) {
|
||||
// domains that are subdomains to other main domains are handled by recursion within walkDomainList()
|
||||
@@ -56,7 +54,7 @@ class PowerDNS extends DnsBase
|
||||
}
|
||||
$this->walkDomainList($domain, $domains);
|
||||
}
|
||||
|
||||
}
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'PowerDNS database updated');
|
||||
$this->reloadDaemon();
|
||||
$this->logger->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Task4 finished');
|
||||
|
||||
@@ -31,7 +31,7 @@ final class Froxlor
|
||||
{
|
||||
|
||||
// Main version variable
|
||||
const VERSION = '2.1.4';
|
||||
const VERSION = '2.1.6';
|
||||
|
||||
// Database version (YYYYMMDDC where C is a daily counter)
|
||||
const DBVERSION = '202312120';
|
||||
|
||||
@@ -69,7 +69,7 @@ class AutoUpdate
|
||||
if (Settings::Get('system.update_channel') == 'testing') {
|
||||
$channel = '/testing';
|
||||
} elseif (Settings::Get('system.update_channel') == 'nightly') {
|
||||
if (empty(Froxlor::BRANDING)) {
|
||||
if (empty(Froxlor::BRANDING) || substr(Froxlor::BRANDING, 0, 1) == '-') {
|
||||
$channel = '/nightly.0000000';
|
||||
} else {
|
||||
$channel = '/' . substr(Froxlor::BRANDING, 1);
|
||||
|
||||
@@ -102,6 +102,14 @@ class Traffic
|
||||
$years_avail = $sel_stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
// sort users by total traffic
|
||||
usort($users, function ($user_a, $user_b) {
|
||||
if ($user_a['total'] == $user_b['total']) {
|
||||
return 0;
|
||||
}
|
||||
return ($user_a['total'] < $user_b['total']) ? 1 : -1;
|
||||
});
|
||||
|
||||
return [
|
||||
'metrics' => $metrics,
|
||||
'users' => $users,
|
||||
|
||||
@@ -2547,6 +2547,7 @@ plugin {
|
||||
</file>
|
||||
</files>
|
||||
<commands index="1">
|
||||
<command><![CDATA[sed -i.bak 's/^!include auth-system.conf.ext/#!include auth-system.conf.ext/' /etc/dovecot/conf.d/10-auth.conf]]></command>
|
||||
<command><![CDATA[service dovecot restart]]></command>
|
||||
</commands>
|
||||
</general>
|
||||
|
||||
@@ -2270,7 +2270,7 @@ Vielen Dank, Ihr Administrator',
|
||||
'install' => [
|
||||
'top' => 'Abschluss',
|
||||
'title' => 'Ein letzter Schritt...',
|
||||
'description' => 'Der untenstehende Befehl lädt, installiert und konfiguriert die benötigten Dienste auf dem System aufgrund der Angaben die während des Installationsprozessen gesammelt wurden.<br><br><span class="text-danger">Führe die gezeigten Befehle als <b>root</b> in der Shell/Konsole des Servers aus.</span>',
|
||||
'description' => 'Der untenstehende Befehl lädt, installiert und konfiguriert die benötigten Dienste auf dem System aufgrund der Angaben die während des Installationsprozessen gesammelt wurden.<br><br><span class="text-danger">Führe die gezeigten Befehle als <b>root</b> in der Shell/Konsole des Servers aus. <b>Beachte bitte</b> das dieser Befehl vorhandene Konfigurationen <b>überschreibt</b> (Sicherungsdateien werden erstellt)!<br>Sollte dies nicht gewünscht sein, wähle <i>Ich werden die Dienste manuell konfigurieren</i> am Ende dieser Seite.</span>',
|
||||
'runcmd' => 'Folgende Befehle ausführen, um die Installation abzuschließen:',
|
||||
'manual_config' => 'Ich werden die Dienste manuell konfigurieren, direkt zum Login umleiten',
|
||||
'waitforconfig' => 'Warte auf Abschluss der Dienstkonfiguration...',
|
||||
|
||||
@@ -2406,7 +2406,7 @@ Yours sincerely, your administrator',
|
||||
'install' => [
|
||||
'top' => 'Finish setup',
|
||||
'title' => 'One last step...',
|
||||
'description' => 'The command below will download, install and configure required services on your system according to the data you have given in this installation process.<br><br><span class="text-danger">Be sure to run the following command as <b>root</b> on the server\'s shell/terminal.</span>',
|
||||
'description' => 'The command below will download, install and configure required services on your system according to the data you have given in this installation process.<br><br><span class="text-danger">Be sure to run the following command as <b>root</b> on the server\'s shell/terminal and <b>be aware</b> that this command will <b>overwrite</b> any existing configuration for the used services (backups will be created)!.<br>If you do not want to overwrite any configurations, select <i>I will manually configure the services</i> at the bottom of this page!</span>',
|
||||
'runcmd' => 'Run the following command to finish the installation:',
|
||||
'manual_config' => 'I will manually configure the services, just take me to the login',
|
||||
'waitforconfig' => 'Waiting for services to be configured...',
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
{% 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) or (field.disabled is defined and field.disabled == true) %} 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 %}/>
|
||||
{% if field.type == 'hidden' and field.display is defined %}
|
||||
<input type="text" readonly class="form-control-plaintext" value="{{ field.display|raw }}">
|
||||
{% endif %}
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
<p>{{ message }}</p>
|
||||
{% if get_config('enable_webupdate') %}
|
||||
<a class='btn d-block btn-outline-warning' href='admin_autoupdate.php?page=overview'>Open updater</a>
|
||||
{% else %}
|
||||
<p>Run the following command in your shell to update:</p>
|
||||
<code>{{ call_static('\\Froxlor\\Froxlor', 'getInstallDir') }}bin/froxlor-cli froxlor:update</code>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
{% if userinfo.adminsession == 1 %}
|
||||
const labelsC = [];
|
||||
const dataValues = [];
|
||||
{% for user in users|sort((a, b) => a.total <=> b.total)|slice(0, 5) %}
|
||||
{% for user in users|slice(0, 5) %}
|
||||
labelsC.push('{{ user.loginname }}');
|
||||
dataValues.push({value: '{{ user.total|default(0) }}', formatted: '{{ user.total|formatBytes }}'});
|
||||
{% endfor %}
|
||||
|
||||
@@ -426,10 +426,10 @@ class MailsTest extends TestCase
|
||||
$this->assertEquals(1, $result['popaccountid']);
|
||||
|
||||
switch (Settings::Get('system.passwordcryptfunc')) {
|
||||
case PASSWORD_ARGON2I:
|
||||
case 'argon2i':
|
||||
$cpPrefix = '{ARGON2I}';
|
||||
break;
|
||||
case PASSWORD_ARGON2ID:
|
||||
case 'argon2id':
|
||||
$cpPrefix = '{ARGON2ID}';
|
||||
break;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user