Compare commits

...

49 Commits

Author SHA1 Message Date
Michael Kaufmann
8cf3f4ee24 set version to 0.10.26 for upcoming maintenance releasae
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-05-14 08:21:53 +02:00
Michael Kaufmann
e83f7634f8 Merge pull request #938 from Froxlor/dependabot/composer/phpmailer/phpmailer-6.4.1
Bump phpmailer/phpmailer from 6.2.0 to 6.4.1
2021-05-04 19:57:10 +02:00
dependabot[bot]
6eb6595a46 Bump phpmailer/phpmailer from 6.2.0 to 6.4.1
Bumps [phpmailer/phpmailer](https://github.com/PHPMailer/PHPMailer) from 6.2.0 to 6.4.1.
- [Release notes](https://github.com/PHPMailer/PHPMailer/releases)
- [Changelog](https://github.com/PHPMailer/PHPMailer/blob/master/changelog.md)
- [Commits](https://github.com/PHPMailer/PHPMailer/compare/v6.2.0...v6.4.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-04 17:43:20 +00:00
Michael Kaufmann
bd48fb7328 catch exception of password-complexity check when changing account password; fixes #935
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-04-14 08:59:44 +02:00
Michael Kaufmann
769525bb56 do not touch/chown error/access log if log is disabled, fixes #934
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-04-12 09:42:25 +02:00
Michael Kaufmann
9195fb3c98 additionally sort by length of username for libnss-extrausers passwd file to have the main user as first in result in any case; fixes #933
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-04-12 09:37:36 +02:00
Michael Kaufmann
82922f7aea add new settings for legal-notes; terms-of-use and privacy-policy; fixes #930
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-24 14:36:48 +01:00
Michael Kaufmann
db1a39b6d9 match composePhpOptions() definition everywhere
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-24 13:49:58 +01:00
Michael Kaufmann
7fbbc2ea0b add vhost replacer {FPMSOCKET} for custom vhost configs; fixes #931
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-24 13:46:24 +01:00
Michael Kaufmann
91d4432108 check rr against possible existing CNAME entries, fixes #927
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-15 17:33:30 +01:00
Michael Kaufmann
c8914312aa Refactoring columns from large table to avoid '1118 Row size too large' error
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-11 09:45:52 +01:00
Michael Kaufmann
3fd89c48e8 set version to 0.10.25 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-05 20:27:55 +01:00
Michael Kaufmann
eceb144a77 also trigger removal of domain in powerdns database if used; refs #923
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-04 12:09:03 +01:00
Michael Kaufmann
1d9651b18a trgger acme.sh removal for domains if customers is being deleted; fixes #923
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-04 12:07:20 +01:00
Michael Kaufmann
49db4e60cb escape passwords for email content (new email-account, new ftp-account and new database); fixes #905
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-03 11:25:58 +01:00
Michael Kaufmann
53e8ccbccb added 'deactivated' parameter to EmailAccounts.update() so admins can disable individual email-accounts, will be overridden if customer is deactivatd and re-enabled; fixes #921
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-03 10:59:16 +01:00
Michael Kaufmann
6d8fc215f1 add description field to panel_domains and mail_virtual table, API parameter 'description' for Domains.add()/Domains.update() and Email.add()/Emails.update(); fixes #910
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-03 10:25:42 +01:00
Michael Kaufmann
f94c303cb3 add API parameter 'show_usages' for Customers.listing() and Customers.get() to return number of domains, and diskspaced used split into webspace_used, mailspace_used and dbspace_used; fixes #912
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-03 09:50:30 +01:00
Michael Kaufmann
2be1873354 fix frontend issue with displaying correct options in domain listing when using php8, thx to cscholz
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-24 19:56:26 +01:00
Michael Kaufmann
d1d36c32fe Merge pull request #920 from RipClaw2971/patch-1
lowercase domain names for ssl-certificate file check (fallback)
2021-02-24 13:07:26 +01:00
RipClaw2971
3b3527348f Update AcmeSh.php
Renewed certificates are not recognized if the domain is in upper/lower case.
2021-02-24 13:00:31 +01:00
Michael Kaufmann
036d5f0713 Merge pull request #919 from nachtgeist/soa
dns: make mail address of SOA records configurable
2021-02-21 18:27:57 +01:00
Daniel Reichelt
a1b8807b0f dns: make mail address of SOA records configurable 2021-02-21 13:00:30 +01:00
Michael Kaufmann
356a087b6a Merge pull request #918 from nachtgeist/pns
dns: check NS entry to be used as primary NS
2021-02-21 09:14:37 +01:00
Michael Kaufmann
0a77fd7150 Merge pull request #917 from nachtgeist/pw
system: validatePassword(): also quote the delimiter ('/')
2021-02-21 09:13:02 +01:00
Daniel Reichelt
67d67a287f system: validatePassword(): also quote the delimiter ('/')
Quoting the default regex delimiter is required for the password
complexity check to work if '/' had been specified as special character
in Froxlor's account settings.
2021-02-21 02:33:46 +01:00
Daniel Reichelt
1f792466bf dns: check NS entry to be used as primary NS
Don't just blindly use the first custom NS entry for SOA, actually check
if it pertains to the domain in question
2021-02-21 02:33:23 +01:00
Michael Kaufmann
5a6343b47c php8 compatibility, fixes #916
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-16 12:38:01 +01:00
Michael Kaufmann
841c529107 fix check for required firstname/name/company in Customers.update(), fixes #915
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-15 23:26:18 +01:00
Michael Kaufmann
41c3f21f0b list only phpenabled and http-enabled domains in php-configuration overview; fixes #911
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-11 16:16:04 +01:00
Michael Kaufmann
b8c0688ba0 added possibility to use 'in' sql-operation in sql_where parameter for Api-calls; php-8 compat fix in admin_traffic
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-11 12:09:42 +01:00
Michael Kaufmann
24e02e99fb set version to 0.10.24 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-05 15:46:08 +01:00
Michael Kaufmann
97bb7b6227 add filecontent to allowed form-fields to not be escaped
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-05 15:44:49 +01:00
Michael Kaufmann
5ceddc8c65 remove not (yet) used cli script
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-05 15:42:38 +01:00
Michael Kaufmann
3a17d03796 add option to specify (optional) fileextension/suffix for generated dkim-private keys; fixes #907
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-20 12:12:41 +01:00
Michael Kaufmann
57ae195930 for percentage calculation always use bytes so we don't compare KiB with GiB or similar
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-18 21:22:29 +01:00
Michael Kaufmann
9b86d576fa do not display usages on dashboard in fixed size-units but dynamically adjusted
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-18 20:49:55 +01:00
Michael Kaufmann
02a12eda13 add missing field 'include_default_vhostconf' to settings table for new installations
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-16 10:50:49 +01:00
Michael Kaufmann
a31da97d66 exclude some formfields from xss-cleaning as it could alter the wanted content
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-13 10:14:51 +01:00
Michael Kaufmann
9f13aa9a12 only pass binding variable for prepared sql statement if variable exists
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-13 08:52:00 +01:00
Michael Kaufmann
2841051649 correctly read in domain's ssl-ips for CAA entries if enabled, fixes #903
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-12 21:08:10 +01:00
Michael Kaufmann
acfbf55d15 Check return of validateFormField() just for non-falsey values and not expect boolean data-type; fixes #904
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-12 19:17:38 +01:00
Michael Kaufmann
5848df28fd Merge pull request #902 from bashgeek/master
Put in trailing slash to /awstats/ location in nginx config
2021-01-12 12:25:22 +01:00
Michael Kaufmann
21925f48c3 set minimum required php-version to 7.1 and recommended php-version to 7.4
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-06 13:36:35 +01:00
Daniel
17a64c58c2 Put in a trailing "/" for /awstats/ location 2020-12-31 16:01:42 +08:00
Daniel
0ca38cff31 Merge pull request #1 from Froxlor/master
up
2020-12-31 15:59:07 +08:00
Michael Kaufmann
5efc1849b4 fix hide-incompatible-settings feature
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-30 17:16:15 +01:00
Michael Kaufmann
f213d666e2 fix typo
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-30 16:46:01 +01:00
Michael Kaufmann
78495b6487 update link to perl-fastcgi wiki on nginx.com; added setting to hide incompatible settings (depending on webserver)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-30 16:41:26 +01:00
57 changed files with 748 additions and 227 deletions

View File

@@ -265,7 +265,37 @@ return array(
'traffic.mail' => $lng['menue']['traffic']['traffic'] . " / Mail"
),
'save_method' => 'storeSettingField'
)
),
'panel_imprint_url' => array(
'label' => $lng['serversettings']['imprint_url'],
'settinggroup' => 'panel',
'varname' => 'imprint_url',
'type' => 'string',
'string_type' => 'url',
'string_emptyallowed' => true,
'default' => '',
'save_method' => 'storeSettingField'
),
'panel_terms_url' => array(
'label' => $lng['serversettings']['terms_url'],
'settinggroup' => 'panel',
'varname' => 'terms_url',
'type' => 'string',
'string_type' => 'url',
'string_emptyallowed' => true,
'default' => '',
'save_method' => 'storeSettingField'
),
'panel_privacy_url' => array(
'label' => $lng['serversettings']['privacy_url'],
'settinggroup' => 'panel',
'varname' => 'privacy_url',
'type' => 'string',
'string_type' => 'url',
'string_emptyallowed' => true,
'default' => '',
'save_method' => 'storeSettingField'
),
)
)
)

View File

@@ -270,6 +270,14 @@ return array(
'default' => true,
'save_method' => 'storeSettingField'
),
'hide_incompatible_settings' => array(
'label' => $lng['serversettings']['hide_incompatible_settings'],
'settinggroup' => 'system',
'varname' => 'hide_incompatible_settings',
'type' => 'bool',
'default' => false,
'save_method' => 'storeSettingField'
),
)
)
)

View File

@@ -132,6 +132,16 @@ return array(
'int_min' => 3600, /* 1 hour */
'int_max' => 2147483647, /* integer max */
'save_method' => 'storeSettingField'
),
'system_soaemail' => array(
'label' => $lng['serversettings']['soaemail'],
'settinggroup' => 'system',
'varname' => 'soaemail',
'type' => 'string',
'string_type' => 'mail',
'string_emptyallowed' => true,
'default' => '',
'save_method' => 'storeSettingField'
)
)
)

View File

@@ -39,6 +39,15 @@ return array(
'default' => '/etc/postfix/dkim/',
'save_method' => 'storeSettingField'
),
'dkim_privkeysuffix' => array(
'label' => $lng['dkim']['privkeysuffix'],
'settinggroup' => 'dkim',
'varname' => 'privkeysuffix',
'type' => 'string',
'string_regexp' => '/^[a-z0-9\._]+$/i',
'default' => '.priv',
'save_method' => 'storeSettingField'
),
'dkim_domains' => array(
'label' => $lng['dkim']['dkim_domains'],
'settinggroup' => 'dkim',

View File

@@ -57,6 +57,12 @@ if (isset($_POST['id'])) {
if ($page == 'overview') {
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_index");
$params = [];
if ($userinfo['customers_see_all'] == '0') {
$params = [
'adminid' => $userinfo['adminid']
];
}
$overview_stmt = Database::prepare("SELECT COUNT(*) AS `number_customers`,
SUM(`diskspace_used`) AS `diskspace_used`,
SUM(`mysqls_used`) AS `mysqls_used`,
@@ -68,20 +74,18 @@ if ($page == 'overview') {
SUM(`subdomains_used`) AS `subdomains_used`,
SUM(`traffic_used`) AS `traffic_used`
FROM `" . TABLE_PANEL_CUSTOMERS . "`" . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid "));
$overview = Database::pexecute_first($overview_stmt, array(
'adminid' => $userinfo['adminid']
));
$overview = Database::pexecute_first($overview_stmt, $params);
$dec_places = Settings::Get('panel.decimal_places');
$overview['traffic_used'] = round($overview['traffic_used'] / (1024 * 1024), $dec_places);
$overview['diskspace_used'] = round($overview['diskspace_used'] / 1024, $dec_places);
$overview['traffic_bytes_used'] = $overview['traffic_used'] * 1024;
$overview['traffic_used'] = \Froxlor\PhpHelper::sizeReadable($overview['traffic_used'] * 1024, null, 'bi');
$overview['diskspace_bytes_used'] = $overview['diskspace_used'] * 1024;
$overview['diskspace_used'] = \Froxlor\PhpHelper::sizeReadable($overview['diskspace_used'] * 1024, null, 'bi');
$number_domains_stmt = Database::prepare("
SELECT COUNT(*) AS `number_domains` FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `parentdomainid`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid"));
$number_domains = Database::pexecute_first($number_domains_stmt, array(
'adminid' => $userinfo['adminid']
));
$number_domains = Database::pexecute_first($number_domains_stmt, $params);
$overview['number_domains'] = $number_domains['number_domains'];
@@ -111,11 +115,17 @@ if ($page == 'overview') {
}
$dec_places = Settings::Get('panel.decimal_places');
$userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, $dec_places);
$userinfo['diskspace_used'] = round($userinfo['diskspace_used'] / 1024, $dec_places);
$userinfo['traffic'] = round($userinfo['traffic'] / (1024 * 1024), $dec_places);
$userinfo['traffic_used'] = round($userinfo['traffic_used'] / (1024 * 1024), $dec_places);
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'customers domains diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains');
// get everything in bytes for the percentage calculation on the dashboard
$userinfo['diskspace_bytes'] = ($userinfo['diskspace'] > -1) ? $userinfo['diskspace'] * 1024 : -1;
$userinfo['diskspace_bytes_used'] = $userinfo['diskspace_used'] * 1024;
$userinfo['traffic_bytes'] = ($userinfo['traffic'] > -1) ? $userinfo['traffic'] * 1024 : - 1;
$userinfo['traffic_bytes_used'] = $userinfo['traffic_used'] * 1024;
$userinfo['diskspace'] = ($userinfo['diskspace'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['diskspace'] * 1024, null, 'bi') : - 1;
$userinfo['diskspace_used'] = \Froxlor\PhpHelper::sizeReadable($userinfo['diskspace_used'] * 1024, null, 'bi');
$userinfo['traffic'] = ($userinfo['traffic'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['traffic'] * 1024, null, 'bi') : - 1;
$userinfo['traffic_used'] = \Froxlor\PhpHelper::sizeReadable($userinfo['traffic_used'] * 1024, null, 'bi');
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'customers domains diskspace diskspace_bytes traffic traffic_bytes mysqls emails email_accounts email_forwarders email_quota ftps subdomains');
$userinfo['custom_notes'] = ($userinfo['custom_notes'] != '') ? nl2br($userinfo['custom_notes']) : '';
@@ -183,8 +193,12 @@ if ($page == 'overview') {
\Froxlor\UI\Response::standard_error('oldpasswordnotcorrect');
}
$new_password = \Froxlor\Validate\Validate::validate($_POST['new_password'], 'new password');
$new_password_confirm = \Froxlor\Validate\Validate::validate($_POST['new_password_confirm'], 'new password confirm');
try {
$new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password');
$new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm');
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
if ($old_password == '') {
\Froxlor\UI\Response::standard_error(array(

View File

@@ -56,6 +56,26 @@ if ($page == 'overview' || $page == 'customers') {
$maxyears = date("Y") - $minyear['year'];
}
$params = [];
if ($userinfo['customers_see_all'] == '0') {
$params = [
'id' => $userinfo['adminid']
];
}
$customer_name_list_stmt = Database::prepare("
SELECT `customerid`,`company`,`name`,`firstname`
FROM `" . TABLE_PANEL_CUSTOMERS . "`
WHERE `deactivated`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :id") . "
ORDER BY name"
);
$traffic_list_stmt = Database::prepare("
SELECT month, SUM(http+ftp_up+ftp_down+mail)*1024 AS traffic
FROM `" . TABLE_PANEL_TRAFFIC . "`
WHERE year = :year AND `customerid` = :id
GROUP BY month ORDER BY month"
);
for ($years = 0; $years <= $maxyears; $years ++) {
$overview['year'] = date("Y") - $years;
@@ -76,14 +96,7 @@ if ($page == 'overview' || $page == 'customers') {
'dec' => 0
);
$customer_name_list_stmt = Database::prepare("
SELECT `customerid`,`company`,`name`,`firstname`
FROM `" . TABLE_PANEL_CUSTOMERS . "`
WHERE `deactivated`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :id") . "
ORDER BY name");
Database::pexecute($customer_name_list_stmt, array(
'id' => $userinfo['adminid']
));
Database::pexecute($customer_name_list_stmt, $params);
while ($customer_name = $customer_name_list_stmt->fetch(PDO::FETCH_ASSOC)) {
@@ -104,11 +117,6 @@ if ($page == 'overview' || $page == 'customers') {
'dec' => '-'
);
$traffic_list_stmt = Database::prepare("
SELECT month, SUM(http+ftp_up+ftp_down+mail)*1024 AS traffic
FROM `" . TABLE_PANEL_TRAFFIC . "`
WHERE year = :year AND `customerid` = :id
GROUP BY month ORDER BY month");
Database::pexecute($traffic_list_stmt, array(
'year' => (date("Y") - $years),
'id' => $customer_name['customerid']

View File

@@ -30,7 +30,7 @@
"docs": "https://github.com/Froxlor/Froxlor/wiki"
},
"require": {
"php": ">=7.0",
"php": ">=7.1",
"ext-session": "*",
"ext-ctype": "*",
"ext-pdo": "*",

18
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "3a662afec2507126181e0f3bbf37dd6a",
"content-hash": "6b4d603703c6ace66f732d1abff8e2f3",
"packages": [
{
"name": "froxlor/idna-convert-legacy",
@@ -150,16 +150,16 @@
},
{
"name": "phpmailer/phpmailer",
"version": "v6.2.0",
"version": "v6.4.1",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "e38888a75c070304ca5514197d4847a59a5c853f"
"reference": "9256f12d8fb0cd0500f93b19e18c356906cbed3d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e38888a75c070304ca5514197d4847a59a5c853f",
"reference": "e38888a75c070304ca5514197d4847a59a5c853f",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/9256f12d8fb0cd0500f93b19e18c356906cbed3d",
"reference": "9256f12d8fb0cd0500f93b19e18c356906cbed3d",
"shasum": ""
},
"require": {
@@ -177,7 +177,7 @@
"yoast/phpunit-polyfills": "^0.2.0"
},
"suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset",
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging",
@@ -214,7 +214,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.2.0"
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.4.1"
},
"funding": [
{
@@ -222,7 +222,7 @@
"type": "github"
}
],
"time": "2020-11-25T15:24:57+00:00"
"time": "2021-04-29T12:25:04+00:00"
},
{
"name": "psr/log",
@@ -4218,7 +4218,7 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=7.0",
"php": ">=7.1",
"ext-session": "*",
"ext-ctype": "*",
"ext-pdo": "*",

View File

@@ -93,22 +93,30 @@ if ($page == 'overview') {
'cid' => $userinfo['customerid']
));
if ($usages)
{
$userinfo['diskspace_used'] = round($usages['webspace'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['mailspace_used'] = round($usages['mail'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['dbspace_used'] = round($usages['mysql'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['total_used'] = round(($usages['webspace'] + $usages['mail'] + $usages['mysql']) / 1024, Settings::Get('panel.decimal_places'));
// get everything in bytes for the percentage calculation on the dashboard
$userinfo['diskspace_bytes'] = ($userinfo['diskspace'] > -1) ? $userinfo['diskspace'] * 1024 : -1;
$userinfo['traffic_bytes'] = ($userinfo['traffic'] > -1) ? $userinfo['traffic'] * 1024 : - 1;
$userinfo['traffic_bytes_used'] = $userinfo['traffic_used'] * 1024;
if ($usages) {
$userinfo['diskspace_used'] = \Froxlor\PhpHelper::sizeReadable($usages['webspace'] * 1024, null, 'bi');
$userinfo['mailspace_used'] = \Froxlor\PhpHelper::sizeReadable($usages['mail'] * 1024, null, 'bi');
$userinfo['dbspace_used'] = \Froxlor\PhpHelper::sizeReadable($usages['mysql'] * 1024, null, 'bi');
$userinfo['total_used'] = \Froxlor\PhpHelper::sizeReadable(($usages['webspace'] + $usages['mail'] + $usages['mysql']) * 1024, null, 'bi');
$userinfo['diskspace_bytes_used'] = $usages['webspace'] * 1024;
$userinfo['total_bytes_used'] = ($usages['webspace'] + $usages['mail'] + $usages['mysql']) * 1024;
} else {
$userinfo['diskspace_used'] = 0;
$userinfo['mailspace_used'] = 0;
$userinfo['dbspace_used'] = 0;
$userinfo['total_used'] = 0;
$userinfo['diskspace_bytes_used'] = 0;
$userinfo['total_bytes_used'] = 0;
}
$userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['traffic'] = round($userinfo['traffic'] / (1024 * 1024), Settings::Get('panel.decimal_places'));
$userinfo['traffic_used'] = round($userinfo['traffic_used'] / (1024 * 1024), Settings::Get('panel.decimal_places'));
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains');
$userinfo['diskspace'] = ($userinfo['diskspace'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['diskspace'] * 1024, null, 'bi') : - 1;
$userinfo['traffic'] = ($userinfo['traffic'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['traffic'] * 1024, null, 'bi') : - 1;
$userinfo['traffic_used'] = \Froxlor\PhpHelper::sizeReadable($userinfo['traffic_used'] * 1024, null, 'bi');
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace diskspace_bytes traffic traffic_bytes mysqls emails email_accounts email_forwarders email_quota ftps subdomains');
$userinfo['custom_notes'] = ($userinfo['custom_notes'] != '') ? nl2br($userinfo['custom_notes']) : '';
@@ -123,19 +131,25 @@ if ($page == 'overview') {
if ($userinfo['perlenabled'] == '1')
$se[] = "Perl/CGI";
if ($userinfo['api_allowed'] == '1')
$se[] = '<a href="customer_index.php?s='.$s.'&page=apikeys">API</a>';
$se[] = '<a href="customer_index.php?s=' . $s . '&page=apikeys">API</a>';
$services_enabled = implode(", ", $se);
eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/index') . "\";");
} elseif ($page == 'change_password') {
if (isset($_POST['send']) && $_POST['send'] == 'send') {
$old_password = \Froxlor\Validate\Validate::validate($_POST['old_password'], 'old password');
if (! \Froxlor\System\Crypt::validatePasswordLogin($userinfo, $old_password, TABLE_PANEL_CUSTOMERS, 'customerid')) {
\Froxlor\UI\Response::standard_error('oldpasswordnotcorrect');
}
$new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password');
$new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm');
try {
$new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password');
$new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm');
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
if ($old_password == '') {
\Froxlor\UI\Response::standard_error(array(

View File

@@ -114,7 +114,7 @@ if ($action == '2fa_entercode') {
));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row['customer'] == $loginname) {
if ($row && $row['customer'] == $loginname) {
$table = "`" . TABLE_PANEL_CUSTOMERS . "`";
$uid = 'customerid';
$adminsession = '0';
@@ -142,7 +142,7 @@ if ($action == '2fa_entercode') {
"loginname" => $loginname
));
$row3 = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row3['customer'] == $loginname) {
if ($row3 && $row3['customer'] == $loginname) {
$table = "`" . TABLE_PANEL_CUSTOMERS . "`";
$uid = 'customerid';
$adminsession = '0';
@@ -181,7 +181,7 @@ if ($action == '2fa_entercode') {
$row = $stmt->fetch(PDO::FETCH_ASSOC);
}
if ($row['admin'] == $loginname) {
if ($row && $row['admin'] == $loginname) {
$table = "`" . TABLE_PANEL_ADMINS . "`";
$uid = 'adminid';
$adminsession = '1';

View File

@@ -71,6 +71,7 @@ CREATE TABLE `mail_virtual` (
`customerid` int(11) NOT NULL default '0',
`popaccountid` int(11) NOT NULL default '0',
`iscatchall` tinyint(1) unsigned NOT NULL default '0',
`description` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `email` (`email`)
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -269,12 +270,13 @@ CREATE TABLE `panel_domains` (
`writeaccesslog` tinyint(1) DEFAULT '1',
`writeerrorlog` tinyint(1) DEFAULT '1',
`override_tls` tinyint(1) DEFAULT '0',
`ssl_protocols` text,
`ssl_cipher_list` text,
`tlsv13_cipher_list` text,
`ssl_protocols` varchar(255) NOT NULL DEFAULT '',
`ssl_cipher_list` varchar(500) NOT NULL DEFAULT '',
`tlsv13_cipher_list` varchar(500) NOT NULL DEFAULT '',
`ssl_enabled` tinyint(1) DEFAULT '1',
`ssl_honorcipherorder` tinyint(1) DEFAULT '0',
`ssl_sessiontickets` tinyint(1) DEFAULT '1',
`description` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `customerid` (`customerid`),
KEY `parentdomain` (`parentdomainid`),
@@ -387,6 +389,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('dkim', 'dkim_domains', 'domains'),
('dkim', 'dkim_dkimkeys', 'dkim-keys.conf'),
('dkim', 'dkimrestart_command', '/etc/init.d/dkim-filter restart'),
('dkim', 'privkeysuffix', '.priv'),
('admin', 'show_news_feed', '0'),
('admin', 'show_version_login', '0'),
('admin', 'show_version_footer', '0'),
@@ -671,6 +674,9 @@ opcache.interned_strings_buffer'),
('system', 'froxloraliases', ''),
('system', 'apply_specialsettings_default', '1'),
('system', 'apply_phpconfigs_default', '1'),
('system', 'hide_incompatible_settings', '0'),
('system', 'include_default_vhostconf', '0'),
('system', 'soaemail', ''),
('api', 'enabled', '0'),
('2fa', 'enabled', '1'),
('panel', 'decimal_places', '4'),
@@ -705,8 +711,11 @@ opcache.interned_strings_buffer'),
('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'customer_hide_options', ''),
('panel', 'is_configured', '0'),
('panel', 'version', '0.10.23.1'),
('panel', 'db_version', '202009070');
('panel', 'imprint_url', ''),
('panel', 'terms_url', ''),
('panel', 'privacy_url', ''),
('panel', 'version', '0.10.26'),
('panel', 'db_version', '202103240');
DROP TABLE IF EXISTS `panel_tasks`;

View File

@@ -1036,11 +1036,11 @@ class FroxlorInstall
// check for correct php version
$content .= $this->_status_message('begin', $this->_lng['requirements']['phpversion']);
if (version_compare("7.0.0", PHP_VERSION, ">=")) {
if (version_compare("7.1.0", PHP_VERSION, ">=")) {
$content .= $this->_status_message('red', $this->_lng['requirements']['notfound'] . ' (' . PHP_VERSION . ')');
$_die = true;
} else {
if (version_compare("7.1.0", PHP_VERSION, ">=")) {
if (version_compare("7.4.0", PHP_VERSION, ">=")) {
$content .= $this->_status_message('orange', $this->_lng['requirements']['newerphpprefered'] . ' (' . PHP_VERSION . ')');
} else {
$content .= $this->_status_message('green', PHP_VERSION);

View File

@@ -699,6 +699,107 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.22')) {
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.23')) {
showUpdateStep("Updating from 0.10.23 to 0.10.23.1", false);
\Froxlor\Froxlor::updateToVersion('0.10.23.1');
showUpdateStep("Updating from 0.10.23 to 0.10.23.1", false);
\Froxlor\Froxlor::updateToVersion('0.10.23.1');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202009070')) {
showUpdateStep("Adding setting to hide incompatible settings", true);
Settings::AddNew("system.hide_incompatible_settings", '0');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202012300');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202012300')) {
showUpdateStep("Adding setting for DKIM private key extension/suffix", true);
Settings::AddNew("dkim.privkeysuffix", '.priv');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202101200');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.23.1')) {
showUpdateStep("Updating from 0.10.23.1 to 0.10.24", false);
\Froxlor\Froxlor::updateToVersion('0.10.24');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202101200')) {
showUpdateStep("Adding setting for mail address used in SOA records", true);
Settings::AddNew("system.soaemail", '');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202102200');
}
/*
* skip due to potential "1118 Row size too large" error
*
if (\Froxlor\Froxlor::isDatabaseVersion('202102200')) {
showUpdateStep("Add new description fields to mail and domain table", true);
Database::query("ALTER TABLE panel_domains ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `ssl_sessiontickets`;");
Database::query("ALTER TABLE mail_virtual ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `iscatchall`");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202103030');
}
*/
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.24')) {
showUpdateStep("Updating from 0.10.24 to 0.10.25", false);
\Froxlor\Froxlor::updateToVersion('0.10.25');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202102200') || \Froxlor\Froxlor::isDatabaseVersion('202103030')) {
showUpdateStep("Refactoring columns from large tables", true);
Database::query("ALTER TABLE panel_domains CHANGE `ssl_protocols` `ssl_protocols` varchar(255) NOT NULL DEFAULT '';");
Database::query("ALTER TABLE panel_domains CHANGE `ssl_cipher_list` `ssl_cipher_list` varchar(500) NOT NULL DEFAULT '';");
Database::query("ALTER TABLE panel_domains CHANGE `tlsv13_cipher_list` `tlsv13_cipher_list` varchar(500) NOT NULL DEFAULT '';");
lastStepStatus(0);
showUpdateStep("Add new description fields to mail and domain table", true);
$result = Database::query("DESCRIBE `panel_domains`");
$columnfound = 0;
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
if ($row['Field'] == 'description') {
$columnfound = 1;
}
}
if (! $columnfound) {
Database::query("ALTER TABLE panel_domains ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `ssl_sessiontickets`;");
}
$result = Database::query("DESCRIBE `mail_virtual`");
$columnfound = 0;
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
if ($row['Field'] == 'description') {
$columnfound = 1;
}
}
if (! $columnfound) {
Database::query("ALTER TABLE mail_virtual ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `iscatchall`");
}
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202103110');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202103110')) {
showUpdateStep("Adding settings for imprint, terms of use and privacy policy URLs", true);
Settings::AddNew("panel.imprint_url", '');
Settings::AddNew("panel.terms_url", '');
Settings::AddNew("panel.privacy_url", '');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202103240');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.25')) {
showUpdateStep("Updating from 0.10.25 to 0.10.26", false);
\Froxlor\Froxlor::updateToVersion('0.10.26');
}

View File

@@ -310,6 +310,13 @@ abstract class ApiCommand extends ApiParameter
} elseif (in_array($valoper['op'], $ops)) {
$condition .= $field . ' ' . $valoper['op'] . ':' . $cleanfield;
$query_fields[':' . $cleanfield] = $valoper['value'] ?? '';
} elseif (strtolower($valoper['op']) == 'in' && is_array($valoper['value']) && count($valoper['value']) > 0) {
$condition .= $field . ' ' . $valoper['op'] . ' (';
foreach ($valoper['value'] as $incnt => $invalue) {
$condition .= ":" . $cleanfield . $incnt . ", ";
$query_fields[':' . $cleanfield . $incnt] = $invalue ?? '';
}
$condition = substr($condition, 0, - 2) . ')';
} else {
continue;
}
@@ -518,7 +525,7 @@ abstract class ApiCommand extends ApiParameter
$customer_ids[] = $customer['customerid'];
}
} else {
if (!$this->isInternal() && ! empty($customer_hide_option) && \Froxlor\Settings::IsInList('panel.customer_hide_options', $customer_hide_option)) {
if (! $this->isInternal() && ! empty($customer_hide_option) && \Froxlor\Settings::IsInList('panel.customer_hide_options', $customer_hide_option)) {
throw new \Exception("You cannot access this resource", 405);
}
$customer_ids = array(

View File

@@ -33,7 +33,9 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* optional specify offset for resultset
* @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
*
* @param bool $show_usages
* optional, default false
*
* @access admin
* @throws \Exception
* @return string json-encoded array count|list
@@ -41,6 +43,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
public function listing()
{
if ($this->isAdmin()) {
$show_usages = $this->getBoolParam('show_usages', true, false);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list customers");
$query_fields = array();
$result_stmt = Database::prepare("
@@ -57,7 +60,47 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$params = array_merge($params, $query_fields);
Database::pexecute($result_stmt, $params, true, true);
$result = array();
$domains_stmt = null;
$usages_stmt = null;
if ($show_usages) {
$domains_stmt = Database::prepare("
SELECT COUNT(`id`) AS `domains`
FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `customerid` = :cid
AND `parentdomainid` = '0'
AND `id`<> :stdd
");
$usages_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_DISKSPACE . "`
WHERE `customerid` = :cid
ORDER BY `stamp` DESC LIMIT 1
");
}
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
if ($show_usages) {
// get number of domains
Database::pexecute($domains_stmt, array(
'cid' => $row['customerid'],
'stdd' => $row['standardsubdomain']
));
$domains = $domains_stmt->fetch(\PDO::FETCH_ASSOC);
$row['domains'] = intval($domains['domains']);
// get disk-space usages for web, mysql and mail
$usages = Database::pexecute_first($usages_stmt, array(
'cid' => $row['customerid']
));
if ($usages) {
$row['webspace_used'] = $usages['webspace'];
$row['mailspace_used'] = $usages['mail'];
$row['dbspace_used'] = $usages['mysql'];
} else {
$row['webspace_used'] = 0;
$row['mailspace_used'] = 0;
$row['dbspace_used'] = 0;
}
}
$result[] = $row;
}
return $this->response(200, "successful", array(
@@ -103,6 +146,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* optional, the customer-id
* @param string $loginname
* optional, the loginname
* @param bool $show_usages
* optional, default false
*
* @access admin, customer
* @throws \Exception
@@ -113,6 +158,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$id = $this->getParam('id', true, 0);
$ln_optional = ($id <= 0 ? false : true);
$loginname = $this->getParam('loginname', $ln_optional, '');
$show_usages = $this->getBoolParam('show_usages', true, false);
if ($this->isAdmin()) {
$result_stmt = Database::prepare("
@@ -142,6 +188,40 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
if (! $this->isAdmin() && $result['custom_notes_show'] != 1) {
$result['custom_notes'] = "";
}
if ($show_usages) {
// get number of domains
$domains_stmt = Database::prepare("
SELECT COUNT(`id`) AS `domains`
FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `customerid` = :cid
AND `parentdomainid` = '0'
AND `id`<> :stdd
");
Database::pexecute($domains_stmt, array(
'cid' => $result['customerid'],
'stdd' => $result['standardsubdomain']
));
$domains = $domains_stmt->fetch(\PDO::FETCH_ASSOC);
$result['domains'] = intval($domains['domains']);
// get disk-space usages for web, mysql and mail
$usages_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_DISKSPACE . "`
WHERE `customerid` = :cid
ORDER BY `stamp` DESC LIMIT 1
");
$usages = Database::pexecute_first($usages_stmt, array(
'cid' => $result['customerid']
));
if ($usages) {
$result['webspace_used'] = $usages['webspace'];
$result['mailspace_used'] = $usages['mail'];
$result['dbspace_used'] = $usages['mysql'];
} else {
$result['webspace_used'] = 0;
$result['mailspace_used'] = 0;
$result['dbspace_used'] = 0;
}
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get customer '" . $result['loginname'] . "'");
return $this->response(200, "successful", $result);
}
@@ -873,7 +953,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$email = $this->getParam('email', true, $idna_convert->decode($result['email']));
$name = $this->getParam('name', true, $result['name']);
$firstname = $this->getParam('firstname', true, $result['firstname']);
$company_required = (! empty($name) && empty($firstname)) || (empty($name) && ! empty($firstname)) || (empty($name) && empty($firstname));
$company_required = empty($result['company']) && ((! empty($name) && empty($firstname)) || (empty($name) && ! empty($firstname)) || (empty($name) && empty($firstname)));
$company = $this->getParam('company', ($company_required ? false : true), $result['company']);
$street = $this->getParam('street', true, $result['street']);
$zipcode = $this->getParam('zipcode', true, $result['zipcode']);
@@ -1411,7 +1491,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
), true, true);
// first gather all domain-id's to clean up panel_domaintoip, dns-entries and certificates accordingly
$did_stmt = Database::prepare("SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");
$did_stmt = Database::prepare("SELECT `id`, `domain` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");
Database::pexecute($did_stmt, array(
'id' => $id
), true, true);
@@ -1431,6 +1511,10 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
Database::pexecute($stmt, array(
'did' => $row['id']
), true, true);
// remove domains DNS from powerDNS if used, #581
\Froxlor\System\Cronjob::inserttask('11', $result['domain']);
// remove domain from acme.sh / lets encrypt if used
\Froxlor\System\Cronjob::inserttask('12', $row['domain']);
}
// remove customer domains
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");

View File

@@ -136,8 +136,24 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
// types
if ($type == 'A' && filter_var($content, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) {
$errors[] = $this->lng['error']['dns_arec_noipv4'];
} elseif ($type == 'A') {
// check whether there is a CNAME-record for the same resource
foreach ($dom_entries as $existing_entries) {
if ($existing_entries['type'] == 'CNAME' && $existing_entries['record'] == $record) {
$errors[] = $this->lng['error']['dns_other_nomorerr'];
break;
}
}
} elseif ($type == 'AAAA' && filter_var($content, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
$errors[] = $this->lng['error']['dns_aaaarec_noipv6'];
} elseif ($type == 'AAAA') {
// check whether there is a CNAME-record for the same resource
foreach ($dom_entries as $existing_entries) {
if ($existing_entries['type'] == 'CNAME' && $existing_entries['record'] == $record) {
$errors[] = $this->lng['error']['dns_other_nomorerr'];
break;
}
}
} elseif ($type == 'CAA' && ! empty($content)) {
$re = '/(?\'critical\'\d)\h*(?\'type\'iodef|issue|issuewild)\h*(?\'value\'(?\'issuevalue\'"(?\'domain\'(?=.{3,128}$)(?>(?>[a-zA-Z0-9]+[a-zA-Z0-9-]*[a-zA-Z0-9]+|[a-zA-Z0-9]+)\.)*(?>[a-zA-Z]{2,}|[a-zA-Z0-9]{2,}\.[a-zA-Z]{2,}))[;\h]*(?\'parameters\'(?>[a-zA-Z0-9]{1,60}=[a-zA-Z0-9]{1,60}\h*)+)?")|(?\'iodefvalue\'"(?\'url\'(mailto:.*|http:\/\/.*|https:\/\/.*))"))/';
preg_match($re, $content, $matches);
@@ -198,6 +214,10 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$errors[] = $this->lng['error']['dns_mx_noalias'];
break;
}
elseif ($existing_entries['type'] == 'CNAME' && $existing_entries['record'] == $record) {
$errors[] = $this->lng['error']['dns_other_nomorerr'];
break;
}
}
}
// append trailing dot (again)
@@ -210,6 +230,14 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
}
if (! \Froxlor\Validate\Validate::validateDomain($content)) {
$errors[] = $this->lng['error']['dns_ns_invaliddom'];
} else {
// check whether there is a CNAME-record for the same resource
foreach ($dom_entries as $existing_entries) {
if ($existing_entries['type'] == 'CNAME' && $existing_entries['record'] == $record) {
$errors[] = $this->lng['error']['dns_other_nomorerr'];
break;
}
}
}
// append trailing dot (again)
$content .= '.';

View File

@@ -288,6 +288,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional list of allowed/used ssl/tls ciphers, see system.ssl_cipher_list setting, only used/required if $override_tls is true, default empty or system.ssl_cipher_list setting if $override_tls is true
* @param string $tlsv13_cipher_list
* optional list of allowed/used tls-1.3 specific ciphers, see system.tlsv13_cipher_list setting, only used/required if $override_tls is true, default empty or system.tlsv13_cipher_list setting if $override_tls is true
* @param string $description
* optional custom description (currently not used/shown in the frontend), default empty
*
* @access admin
* @throws \Exception
@@ -354,6 +356,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$tlsv13_cipher_list = $this->getParam('tlsv13_cipher_list', true, Settings::Get('system.tlsv13_cipher_list'));
}
}
$description = $this->getParam('description', true, '');
// validation
$p_domain = strtolower($p_domain);
@@ -728,7 +731,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'tlsv13_cipher_list' => $tlsv13_cipher_list,
'sslenabled' => $sslenabled,
'honorcipherorder' => $honorcipherorder,
'sessiontickets' => $sessiontickets
'sessiontickets' => $sessiontickets,
'description' => $description
);
$ins_stmt = Database::prepare("
@@ -780,7 +784,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`tlsv13_cipher_list` = :tlsv13_cipher_list,
`ssl_enabled` = :sslenabled,
`ssl_honorcipherorder` = :honorcipherorder,
`ssl_sessiontickets`= :sessiontickets
`ssl_sessiontickets` = :sessiontickets,
`description` = :description
");
Database::pexecute($ins_stmt, $ins_data, true, true);
$domainid = Database::lastInsertId();
@@ -932,6 +937,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional whether to honor the (server) cipher order for this domain. default 0 (false), requires SSL
* @param bool $sessiontickets
* optional whether to enable or disable TLS sessiontickets (RFC 5077) for this domain. default 1 (true), requires SSL
* @param string $description
* optional custom description (currently not used/shown in the frontend), default empty
*
* @access admin
* @throws \Exception
@@ -1027,6 +1034,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$ssl_cipher_list = $result['ssl_cipher_list'];
$tlsv13_cipher_list = $result['tlsv13_cipher_list'];
}
$description = $this->getParam('description', true, $result['description']);
// count subdomain usage of source-domain
$subdomains_stmt = Database::prepare("
@@ -1589,6 +1597,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$update_data['sslenabled'] = $sslenabled;
$update_data['honorcipherorder'] = $honorcipherorder;
$update_data['sessiontickets'] = $sessiontickets;
$update_data['description'] = $description;
$update_data['id'] = $id;
$update_stmt = Database::prepare("
@@ -1634,7 +1643,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`tlsv13_cipher_list` = :tlsv13_cipher_list,
`ssl_enabled` = :sslenabled,
`ssl_honorcipherorder` = :honorcipherorder,
`ssl_sessiontickets` = :sessiontickets
`ssl_sessiontickets` = :sessiontickets,
`description` = :description
WHERE `id` = :id
");
Database::pexecute($update_stmt, $update_data, true, true);

View File

@@ -100,7 +100,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
// alternative email address to send info to
if (Settings::Get('panel.sendalternativemail') == 1) {
$alternative_email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($alternative_email, 'alternative_email', '', '', array(), true));
if (!empty($alternative_email) && ! \Froxlor\Validate\Validate::validateEmail($alternative_email)) {
if (! empty($alternative_email) && ! \Froxlor\Validate\Validate::validateEmail($alternative_email)) {
\Froxlor\UI\Response::standard_error('alternativeemailiswrong', $alternative_email, true);
}
} else {
@@ -192,7 +192,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$replace_arr = array(
'EMAIL' => $email_full,
'USERNAME' => $username,
'PASSWORD' => $password,
'PASSWORD' => htmlentities(htmlentities($password)),
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($customer),
'NAME' => $customer['name'],
'FIRSTNAME' => $customer['firstname'],
@@ -236,7 +236,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$this->mailer()->clearAddresses();
// customer wants to send the e-mail to an alternative email address too
if (Settings::Get('panel.sendalternativemail') == 1 && !empty($alternative_email)) {
if (Settings::Get('panel.sendalternativemail') == 1 && ! empty($alternative_email)) {
// get template for mail subject
$mail_subject = $this->getMailTemplate($customer, 'mails', 'pop_success_alternative_subject', $replace_arr, $this->lng['mails']['pop_success_alternative']['subject']);
// get template for mail body
@@ -302,6 +302,8 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
* optional, update quota
* @param string $email_password
* optional, update password
* @param bool $deactivated
* optional, admin-only
*
* @access admin, customer
* @throws \Exception
@@ -331,6 +333,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$password = $this->getParam('email_password', true, '');
$quota = $this->getParam('email_quota', true, $result['quota']);
$deactivated = $this->getBoolParam('deactivated', true, (strtolower($result['postfix']) == 'n' ? true : false));
// get needed customer info to reduce the email-account-counter by one
$customer = $this->getCustomerData();
@@ -372,6 +375,18 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$quota = 0;
}
if ($this->isAdmin()) {
if (($deactivated == true && strtolower($result['postfix']) == 'y') || ($deactivated == false && strtolower($result['postfix']) == 'n')) {
if (! empty($upd_query)) {
$upd_query .= ", ";
}
$upd_query .= "`postfix` = :postfix, `imap` = :imap, `pop3` = :pop3";
$upd_params['postfix'] = $deactivated ? 'N' : 'Y';
$upd_params['imap'] = $deactivated ? '0' : '1';
$upd_params['pop3'] = $deactivated ? '0' : '1';
}
}
// build update query
if (! empty($upd_query)) {
$upd_stmt = Database::prepare("

View File

@@ -35,6 +35,8 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, required when called as admin (if $customerid is not specified)
* @param string $description
* optional custom description (currently not used/shown in the frontend), default empty
*
* @access admin, customer
* @throws \Exception
@@ -54,6 +56,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
// parameters
$iscatchall = $this->getBoolParam('iscatchall', true, 0);
$description = $this->getParam('description', true, '');
// validation
if (substr($domain, 0, 4) != 'xn--') {
@@ -121,14 +124,16 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
`email` = :email,
`email_full` = :email_full,
`iscatchall` = :iscatchall,
`domainid` = :domainid
`domainid` = :domainid,
`description` = :description
");
$params = array(
"cid" => $customer['customerid'],
"email" => $email,
"email_full" => $email_full,
"iscatchall" => $iscatchall,
"domainid" => $domain_check['id']
"domainid" => $domain_check['id'],
"description" => $description
);
Database::pexecute($stmt, $params, true, true);
@@ -167,7 +172,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$customer_ids = $this->getAllowedCustomerIds('email');
$params['idea'] = ($id <= 0 ? $emailaddr : $id);
$result_stmt = Database::prepare("SELECT v.`id`, v.`email`, v.`email_full`, v.`iscatchall`, v.`destination`, v.`customerid`, v.`popaccountid`, v.`domainid`, u.`quota`
$result_stmt = Database::prepare("SELECT v.`id`, v.`email`, v.`email_full`, v.`iscatchall`, v.`destination`, v.`customerid`, v.`popaccountid`, v.`domainid`, v.`description`, u.`quota`, u.`imap`, u.`pop3`, u.`postfix`, u.`mboxsize`
FROM `" . TABLE_MAIL_VIRTUAL . "` v
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON v.`popaccountid` = u.`id`
WHERE v.`customerid` IN (" . implode(", ", $customer_ids) . ")
@@ -195,6 +200,8 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, required when called as admin (if $customerid is not specified)
* @param boolean $iscatchall
* optional
* @param string $description
* optional custom description (currently not used/shown in the frontend), default empty
*
* @access admin, customer
* @throws \Exception
@@ -227,6 +234,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
// parameters
$iscatchall = $this->getBoolParam('iscatchall', true, $result['iscatchall']);
$description = $this->getParam('description', true, $result['description']);
// get needed customer info to reduce the email-address-counter by one
$customer = $this->getCustomerData();
@@ -256,12 +264,13 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$stmt = Database::prepare("
UPDATE `" . TABLE_MAIL_VIRTUAL . "`
SET `email` = :email , `iscatchall` = :caflag
SET `email` = :email , `iscatchall` = :caflag, `description` = :description
WHERE `customerid`= :cid AND `id`= :id
");
$params = array(
"email" => $email,
"caflag" => $iscatchall,
"description" => $description,
"cid" => $customer['customerid'],
"id" => $id
);
@@ -300,7 +309,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = array();
$query_fields = array();
$result_stmt = Database::prepare("
SELECT m.`id`, m.`domainid`, m.`email`, m.`email_full`, m.`iscatchall`, u.`quota`, m.`destination`, m.`popaccountid`, d.`domain`, u.`mboxsize`
SELECT m.`id`, m.`domainid`, m.`email`, m.`email_full`, m.`iscatchall`, m.`destination`, m.`popaccountid`, d.`domain`, u.`quota`, u.`imap`, u.`pop3`, u.`postfix`, u.`mboxsize`
FROM `" . TABLE_MAIL_VIRTUAL . "` m
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON (m.`domainid` = d.`id`)
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON (m.`popaccountid` = u.`id`)

View File

@@ -245,7 +245,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
'COMPANY' => $customer['company'],
'CUSTOMER_NO' => $customer['customernumber'],
'USR_NAME' => $username,
'USR_PASS' => $password,
'USR_PASS' => htmlentities(htmlentities($password)),
'USR_PATH' => \Froxlor\FileDir::makeCorrectDir(str_replace($customer['documentroot'], "/", $path))
);
// get template for mail subject

View File

@@ -88,13 +88,13 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
// add database info to froxlor
$stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_DATABASES . "`
SET
`customerid` = :customerid,
`databasename` = :databasename,
`description` = :description,
`dbserver` = :dbserver
");
INSERT INTO `" . TABLE_PANEL_DATABASES . "`
SET
`customerid` = :customerid,
`databasename` = :databasename,
`description` = :description,
`dbserver` = :dbserver
");
$params = array(
"customerid" => $customer['customerid'],
"databasename" => $username,
@@ -130,7 +130,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
'COMPANY' => $userinfo['company'],
'CUSTOMER_NO' => $userinfo['customernumber'],
'DB_NAME' => $username,
'DB_PASS' => $password,
'DB_PASS' => htmlentities(htmlentities($password)),
'DB_DESC' => $databasedescription,
'DB_SRV' => $sql_root['host'],
'PMA_URI' => $pma

View File

@@ -59,7 +59,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
);
$query = "SELECT * FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `phpsettingid` = :id";
WHERE `phpsettingid` = :id AND `email_only` = '0' AND `phpenabled` = '1'";
if (! $with_subdomains) {
$query .= " AND `parentdomainid` = '0'";

View File

@@ -200,14 +200,14 @@ abstract class DnsBase
while ($domain = $result_domains_stmt->fetch(\PDO::FETCH_ASSOC)) {
$privkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . '.priv');
$privkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . Settings::Get('dkim.privkeysuffix'));
$pubkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . '.public');
if ($domain['dkim_privkey'] == '' || $domain['dkim_pubkey'] == '') {
$max_dkim_id_stmt = Database::query("SELECT MAX(`dkim_id`) as `max_dkim_id` FROM `" . TABLE_PANEL_DOMAINS . "`");
$max_dkim_id = $max_dkim_id_stmt->fetch(\PDO::FETCH_ASSOC);
$domain['dkim_id'] = (int) $max_dkim_id['max_dkim_id'] + 1;
$privkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . '.priv');
$privkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . Settings::Get('dkim.privkeysuffix'));
\Froxlor\FileDir::safe_exec('openssl genrsa -out ' . escapeshellarg($privkey_filename) . ' ' . Settings::Get('dkim.dkim_keylength'));
$domain['dkim_privkey'] = file_get_contents($privkey_filename);
\Froxlor\FileDir::safe_exec("chmod 0640 " . escapeshellarg($privkey_filename));

View File

@@ -565,7 +565,7 @@ class Apache extends HttpConfigBase
*
* @return string
*/
protected function composePhpOptions($domain, $ssl_vhost = false)
protected function composePhpOptions(&$domain, $ssl_vhost = false)
{
$php_options_text = '';
@@ -788,14 +788,6 @@ class Apache extends HttpConfigBase
));
$logfiles_text .= ' CustomLog "|' . $command . '" ' . $logtype . "\n";
} else {
// Create the logfile if it does not exist (fixes #46)
touch($error_log);
chown($error_log, Settings::Get('system.httpuser'));
chgrp($error_log, Settings::Get('system.httpgroup'));
touch($access_log);
chown($access_log, Settings::Get('system.httpuser'));
chgrp($access_log, Settings::Get('system.httpgroup'));
$logfiles_text .= ' ErrorLog "' . $error_log . '"' . "\n";
$logfiles_text .= ' CustomLog "' . $access_log . '" ' . $logtype . "\n";
}

View File

@@ -24,7 +24,7 @@ use Froxlor\Cron\Http\Php\PhpInterface;
class ApacheFcgi extends Apache
{
protected function composePhpOptions($domain, $ssl_vhost = false)
protected function composePhpOptions(&$domain, $ssl_vhost = false)
{
$php_options_text = '';
@@ -43,6 +43,8 @@ class ApacheFcgi extends Apache
$php_options_text .= ' SuexecUserGroup "' . $domain['loginname'] . '" "' . $domain['loginname'] . '"' . "\n";
}
$domain['fpm_socket'] = $php->getInterface()->getSocketFile();
// mod_proxy stuff for apache-2.4
if (Settings::Get('system.apache24') == '1' && Settings::Get('phpfpm.use_mod_proxy') == '1') {
$filesmatch = $phpconfig['fpm_settings']['limit_extensions'];
@@ -54,7 +56,7 @@ class ApacheFcgi extends Apache
// start block, cut off last pipe and close block
$filesmatch = '(' . str_replace(".", "\.", substr($filesmatch, 0, - 1)) . ')';
$php_options_text .= ' <FilesMatch \.' . $filesmatch . '$>' . "\n";
$php_options_text .= ' SetHandler proxy:unix:' . $php->getInterface()->getSocketFile() . '|fcgi://localhost' . "\n";
$php_options_text .= ' SetHandler proxy:unix:' . $domain['fpm_socket'] . '|fcgi://localhost' . "\n";
$php_options_text .= ' </FilesMatch>' . "\n";
$mypath_dir = new \Froxlor\Http\Directory($domain['documentroot']);
@@ -80,7 +82,7 @@ class ApacheFcgi extends Apache
if ($phpconfig['pass_authorizationheader'] == '1') {
$addheader = " -pass-header Authorization";
}
$php_options_text .= ' FastCgiExternalServer ' . $php->getInterface()->getAliasConfigDir() . $srvName . ' -socket ' . $php->getInterface()->getSocketFile() . ' -idle-timeout ' . $phpconfig['fpm_settings']['idle_timeout'] . $addheader . "\n";
$php_options_text .= ' FastCgiExternalServer ' . $php->getInterface()->getAliasConfigDir() . $srvName . ' -socket ' . $domain['fpm_socket'] . ' -idle-timeout ' . $phpconfig['fpm_settings']['idle_timeout'] . $addheader . "\n";
$php_options_text .= ' <Directory "' . \Froxlor\FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
$filesmatch = $phpconfig['fpm_settings']['limit_extensions'];
$extensions = explode(" ", $filesmatch);

View File

@@ -98,8 +98,12 @@ class HttpConfigBase
'IP' => $ip,
'PORT' => $port,
'SCHEME' => ($is_ssl_vhost) ? 'https' : 'http',
'DOCROOT' => $domain['documentroot']
'DOCROOT' => $domain['documentroot'],
'FPMSOCKET' => ''
);
if ((int) Settings::Get('phpfpm.enabled') == 1 && isset($domain['fpm_socket']) && !empty($domain['fpm_socket'])) {
$templateVars['FPMSOCKET'] = $domain['fpm_socket'];
}
return \Froxlor\PhpHelper::replaceVariables($template, $templateVars);
}

View File

@@ -497,8 +497,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
private static function checkFsFilesAreNewer($domain, $cert_date = 0)
{
$certificate_folder = self::getWorkingDirFromEnv($domain);
$ssl_file = \Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $domain . '.cer');
$certificate_folder = self::getWorkingDirFromEnv(strtolower($domain));
$ssl_file = \Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . strtolower($domain) . '.cer');
if (is_dir($certificate_folder) && file_exists($ssl_file) && is_readable($ssl_file)) {
$cert_data = openssl_x509_parse(file_get_contents($ssl_file));

View File

@@ -364,7 +364,7 @@ class Lighttpd extends HttpConfigBase
return;
}
protected function composePhpOptions($domain)
protected function composePhpOptions(&$domain)
{
return;
}

View File

@@ -22,7 +22,7 @@ use Froxlor\Cron\Http\Php\PhpInterface;
class LighttpdFcgi extends Lighttpd
{
protected function composePhpOptions($domain)
protected function composePhpOptions(&$domain)
{
$php_options_text = '';
@@ -32,10 +32,11 @@ class LighttpdFcgi extends Lighttpd
// vhost data for php-fpm
if ((int) Settings::Get('phpfpm.enabled') == 1) {
$domain['fpm_socket'] = $php->getInterface()->getSocketFile();
$php_options_text = ' fastcgi.server = ( ' . "\n";
$php_options_text .= "\t" . '".php" => (' . "\n";
$php_options_text .= "\t\t" . '"localhost" => (' . "\n";
$php_options_text .= "\t\t" . '"socket" => "' . $php->getInterface()->getSocketFile() . '",' . "\n";
$php_options_text .= "\t\t" . '"socket" => "' . $domain['fpm_socket'] . '",' . "\n";
$php_options_text .= "\t\t" . '"check-local" => "enable",' . "\n";
$php_options_text .= "\t\t" . '"disable-time" => 1' . "\n";
$php_options_text .= "\t" . ')' . "\n";

View File

@@ -970,7 +970,7 @@ class Nginx extends HttpConfigBase
return $returnval;
}
protected function composePhpOptions($domain, $ssl_vhost = false)
protected function composePhpOptions(&$domain, $ssl_vhost = false)
{
$phpopts = '';
if ($domain['phpenabled_customer'] == 1 && $domain['phpenabled_vhost'] == '1') {
@@ -1053,7 +1053,7 @@ class Nginx extends HttpConfigBase
if (Settings::Get('system.awstats_enabled') == '1') {
// awstats
$stats_text .= "\t" . 'location ^~ /awstats {' . "\n";
$stats_text .= "\t" . 'location ^~ /awstats/ {' . "\n";
} else {
// webalizer
$stats_text .= "\t" . 'location ^~ /webalizer {' . "\n";

View File

@@ -22,7 +22,7 @@ use Froxlor\Cron\Http\Php\PhpInterface;
class NginxFcgi extends Nginx
{
protected function composePhpOptions($domain, $ssl_vhost = false)
protected function composePhpOptions(&$domain, $ssl_vhost = false)
{
$php_options_text = '';
@@ -43,7 +43,8 @@ class NginxFcgi extends Nginx
if ($domain['ssl'] == '1' && $ssl_vhost) {
$php_options_text .= "\t\t" . 'fastcgi_param HTTPS on;' . "\n";
}
$php_options_text .= "\t\t" . 'fastcgi_pass unix:' . $php->getInterface()->getSocketFile() . ";\n";
$domain['fpm_socket'] = $php->getInterface()->getSocketFile();
$php_options_text .= "\t\t" . 'fastcgi_pass unix:' . $domain['fpm_socket'] . ";\n";
$php_options_text .= "\t\t" . 'fastcgi_index index.php;' . "\n";
$php_options_text .= "\t}\n\n";

View File

@@ -24,7 +24,7 @@ class Extrausers
{
// passwd
$passwd = '/var/lib/extrausers/passwd';
$sql = "SELECT customerid,username,'x' as password,uid,gid,'Froxlor User' as comment,homedir,shell, login_enabled FROM ftp_users ORDER BY uid ASC";
$sql = "SELECT customerid,username,'x' as password,uid,gid,'Froxlor User' as comment,homedir,shell, login_enabled FROM ftp_users ORDER BY uid, LENGTH(username) ASC";
self::generateFile($passwd, $sql, $cronlog);
// group

View File

@@ -131,9 +131,26 @@ class Dns
}
// additional required records for CAA if activated
if (Settings::Get('system.dns_createcaaentry') && Settings::Get('system.use_ssl') == "1" && !empty($domain['p_ssl_ipandports'])) {
// check for CAA content later
self::addRequiredEntry('@CAA@', 'CAA', $required_entries);
if (Settings::Get('system.dns_createcaaentry') && Settings::Get('system.use_ssl') == "1") {
$result_stmt = Database::prepare("
SELECT i.`ip`, i.`port`, i.`ssl`
FROM " . TABLE_PANEL_IPSANDPORTS . " i
LEFT JOIN " . TABLE_DOMAINTOIP . " dip ON dip.id_ipandports = i.id
WHERE i.ssl = 1 AND dip.id_domain = :domainid
");
Database::pexecute($result_stmt, array(
'domainid' => $domain['id']
));
$ssl_ipandports = array();
while ($ssl_ipandport = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$ssl_ipandports[] = $ssl_ipandport;
}
if (! empty($ssl_ipandports)) {
// check for CAA content later
self::addRequiredEntry('@CAA@', 'CAA', $required_entries);
}
}
// additional required records for SPF and DKIM if activated
@@ -160,16 +177,20 @@ class Dns
// unset special CAA required-entry
unset($required_entries[$entry['type']][md5("@CAA@")]);
}
if (Settings::Get('spf.use_spf') == '1' && $entry['type'] == 'TXT' && $entry['record'] == '@' && (strtolower(substr($entry['content'], 0, 7)) == '"v=spf1' || strtolower(substr($entry['content'], 0, 6)) == 'v=spf1') ) {
if (Settings::Get('spf.use_spf') == '1' && $entry['type'] == 'TXT' && $entry['record'] == '@' && (strtolower(substr($entry['content'], 0, 7)) == '"v=spf1' || strtolower(substr($entry['content'], 0, 6)) == 'v=spf1')) {
// unset special spf required-entry
unset($required_entries[$entry['type']][md5("@SPF@")]);
}
if (empty($primary_ns) && $entry['type'] == 'NS') {
// use the first NS entry as primary ns
if (empty($primary_ns) && $entry['record'] == '@' && $entry['type'] == 'NS') {
// use the first NS entry pertaining to the current domain as primary ns
$primary_ns = $entry['content'];
}
// check for CNAME on @, www- or wildcard-Alias and remove A/AAAA record accordingly
foreach (['@', 'www', '*'] as $crceord) {
foreach ([
'@',
'www',
'*'
] as $crceord) {
if ($entry['type'] == 'CNAME' && $entry['record'] == '@' && (array_key_exists(md5($crceord), $required_entries['A']) || array_key_exists(md5($crceord), $required_entries['AAAA']))) {
unset($required_entries['A'][md5($crceord)]);
unset($required_entries['AAAA'][md5($crceord)]);
@@ -186,16 +207,16 @@ class Dns
if ($froxlorhostname) {
// use all available IP's for the froxlor-hostname
$result_ip_stmt = Database::prepare("
SELECT `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "` GROUP BY `ip`
");
SELECT `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "` GROUP BY `ip`
");
Database::pexecute($result_ip_stmt);
} else {
$result_ip_stmt = Database::prepare("
SELECT `p`.`ip` AS `ip`
FROM `" . TABLE_PANEL_IPSANDPORTS . "` `p`, `" . TABLE_DOMAINTOIP . "` `di`
WHERE `di`.`id_domain` = :domainid AND `p`.`id` = `di`.`id_ipandports`
GROUP BY `p`.`ip`;
");
SELECT `p`.`ip` AS `ip`
FROM `" . TABLE_PANEL_IPSANDPORTS . "` `p`, `" . TABLE_DOMAINTOIP . "` `di`
WHERE `di`.`id_domain` = :domainid AND `p`.`id` = `di`.`id_ipandports`
GROUP BY `p`.`ip`;
");
Database::pexecute($result_ip_stmt, array(
'domainid' => $domain_id
));
@@ -309,6 +330,7 @@ class Dns
}
foreach ($caa_entries as $entry) {
if (empty($entry)) continue;
$zonerecords[] = new DnsEntry('@', 'CAA', $entry);
// additional required records by subdomain setting
if ($domain['wwwserveralias'] == '1') {
@@ -343,7 +365,11 @@ class Dns
}
// PowerDNS does not like multi-line-format
$soa_content = $primary_ns . " " . self::escapeSoaAdminMail(Settings::Get('panel.adminmail')) . " ";
$soa_email = Settings::Get('system.soaemail');
if ($soa_email == "") {
$soa_email = Settings::Get('panel.adminmail');
}
$soa_content = $primary_ns . " " . self::escapeSoaAdminMail($soa_email) . " ";
$soa_content .= $domain['bindserial'] . " ";
// TODO for now, dummy time-periods
$soa_content .= "3600 900 604800 " . (int) Settings::Get('system.defaultttl');

View File

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

View File

@@ -400,10 +400,22 @@ class PhpHelper
*/
public static function cleanGlobal(&$global, &$antiXss)
{
$ignored_fields = [
'system_default_vhostconf',
'system_default_sslvhostconf',
'system_apache_globaldiropt',
'specialsettings',
'ssl_specialsettings',
'default_vhostconf_domain',
'ssl_default_vhostconf_domain',
'filecontent'
];
if (isset($global) && ! empty($global)) {
$tmp = $global;
foreach ($tmp as $index => $value) {
$global[$index] = $antiXss->xss_clean($value);
if (!in_array($index, $ignored_fields)) {
$global[$index] = $antiXss->xss_clean($value);
}
}
}
}

View File

@@ -176,7 +176,7 @@ class Store
if ($returnvalue !== false) {
\Froxlor\System\Cronjob::inserttask('4');
}
return false;
return $returnvalue;
}
public static function storeSettingHostname($fieldname, $fielddata, $newfieldvalue)

View File

@@ -168,7 +168,7 @@ class Crypt
$password = \Froxlor\Validate\Validate::validate($password, '/.*[0-9]+.*/', '/.*[0-9]+.*/', 'notrequiredpasswordcomplexity', array(), $json_response);
}
if (Settings::Get('panel.password_special_char_required')) {
$password = \Froxlor\Validate\Validate::validate($password, '/.*[' . preg_quote(Settings::Get('panel.password_special_char')) . ']+.*/', '/.*[' . preg_quote(Settings::Get('panel.password_special_char')) . ']+.*/', 'notrequiredpasswordcomplexity', array(), $json_response);
$password = \Froxlor\Validate\Validate::validate($password, '/.*[' . preg_quote(Settings::Get('panel.password_special_char'), '/') . ']+.*/', '/.*[' . preg_quote(Settings::Get('panel.password_special_char'), '/') . ']+.*/', 'notrequiredpasswordcomplexity', array(), $json_response);
}
}

View File

@@ -217,7 +217,7 @@ class Form
if (! $only_enabledisable || ($only_enabledisable && isset($fielddetails['overview_option']))) {
$newfieldvalue = self::getFormFieldData($fieldname, $fielddetails, $input);
if ($newfieldvalue != $fielddetails['value']) {
if (($error = \Froxlor\Validate\Form::validateFormField($fieldname, $fielddetails, $newfieldvalue)) !== true) {
if (($error = \Froxlor\Validate\Form::validateFormField($fieldname, $fielddetails, $newfieldvalue)) != true) {
\Froxlor\UI\Response::standard_error($error, $fieldname);
} else {
$changed_fields[$fieldname] = $newfieldvalue;
@@ -443,12 +443,12 @@ class Form
}
}
// if ($do_show) {
$returnvalue = call_user_func(array(
'\\Froxlor\\UI\\Fields',
'getFormFieldOutput' . ucfirst($fielddata['type'])
), $fieldname, $fielddata, $do_show);
// }
if ($do_show || (!$do_show && Settings::Get('system.hide_incompatible_settings') == '0')) {
$returnvalue = call_user_func(array(
'\\Froxlor\\UI\\Fields',
'getFormFieldOutput' . ucfirst($fielddata['type'])
), $fieldname, $fielddata, $do_show);
}
}
return $returnvalue;
}

View File

@@ -167,7 +167,7 @@ return array(
'value' => array()
),
'diskspace' => array(
'label' => $lng['customer']['diskspace'],
'label' => $lng['customer']['diskspace'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => 0,
'maxlength' => 6,
@@ -175,7 +175,7 @@ return array(
'ul_field' => $diskspace_ul
),
'traffic' => array(
'label' => $lng['customer']['traffic'],
'label' => $lng['customer']['traffic'] . ' (' . $lng['customer']['gib'] . ')',
'type' => 'textul',
'value' => 0,
'maxlength' => 4,
@@ -215,7 +215,7 @@ return array(
'ul_field' => $email_forwarders_ul
),
'email_quota' => array(
'label' => $lng['customer']['email_quota'],
'label' => $lng['customer']['email_quota'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => 0,
'maxlength' => 9,

View File

@@ -196,7 +196,7 @@ return array(
)
),
'diskspace' => array(
'label' => $lng['customer']['diskspace'],
'label' => $lng['customer']['diskspace'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => $result['diskspace'],
'maxlength' => 6,
@@ -204,7 +204,7 @@ return array(
'ul_field' => $diskspace_ul
),
'traffic' => array(
'label' => $lng['customer']['traffic'],
'label' => $lng['customer']['traffic'] . ' (' . $lng['customer']['gib'] . ')',
'type' => 'textul',
'value' => $result['traffic'],
'maxlength' => 4,
@@ -244,7 +244,7 @@ return array(
'ul_field' => $email_forwarders_ul
),
'email_quota' => array(
'label' => $lng['customer']['email_quota'],
'label' => $lng['customer']['email_quota'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => $result['email_quota'],
'maxlength' => 9,

View File

@@ -190,7 +190,7 @@ return array(
'image' => 'icons/user_add.png',
'fields' => array(
'diskspace' => array(
'label' => $lng['customer']['diskspace'],
'label' => $lng['customer']['diskspace'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => 0,
'maxlength' => 16,
@@ -198,7 +198,7 @@ return array(
'ul_field' => $diskspace_ul
),
'traffic' => array(
'label' => $lng['customer']['traffic'],
'label' => $lng['customer']['traffic'] . ' (' . $lng['customer']['gib'] . ')',
'type' => 'textul',
'value' => 0,
'maxlength' => 14,
@@ -238,7 +238,7 @@ return array(
'ul_field' => $email_forwarders_ul
),
'email_quota' => array(
'label' => $lng['customer']['email_quota'],
'label' => $lng['customer']['email_quota']. ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => 0,
'maxlength' => 9,

View File

@@ -196,7 +196,7 @@ return array(
'image' => 'icons/user_edit.png',
'fields' => array(
'diskspace' => array(
'label' => $lng['customer']['diskspace'],
'label' => $lng['customer']['diskspace'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => $result['diskspace'],
'maxlength' => 16,
@@ -204,7 +204,7 @@ return array(
'ul_field' => $diskspace_ul
),
'traffic' => array(
'label' => $lng['customer']['traffic'],
'label' => $lng['customer']['traffic'] . ' (' . $lng['customer']['gib'] . ')',
'type' => 'textul',
'value' => $result['traffic'],
'maxlength' => 14,
@@ -244,7 +244,7 @@ return array(
'ul_field' => $email_forwarders_ul
),
'email_quota' => array(
'label' => $lng['customer']['email_quota'],
'label' => $lng['customer']['email_quota'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => $result['email_quota'],
'maxlength' => 9,

View File

@@ -21,11 +21,11 @@
$_deftheme = 'Sparkle';
// validate correct php version
if (version_compare("7.0.0", PHP_VERSION, ">=")) {
if (version_compare("7.1.0", PHP_VERSION, ">=")) {
// get hint-template
$vendor_hint = file_get_contents(dirname(__DIR__) . '/templates/' . $_deftheme . '/misc/phprequirementfailed.tpl');
// replace values
$vendor_hint = str_replace("<FROXLOR_PHPMIN>", "7.0.0", $vendor_hint);
$vendor_hint = str_replace("<FROXLOR_PHPMIN>", "7.1.0", $vendor_hint);
$vendor_hint = str_replace("<CURRENT_VERSION>", PHP_VERSION, $vendor_hint);
$vendor_hint = str_replace("<CURRENT_YEAR>", date('Y', time()), $vendor_hint);
die($vendor_hint);
@@ -480,6 +480,18 @@ if (array_key_exists('css', $_themeoptions['variants'][$themevariant]) && is_arr
eval("\$header = \"" . \Froxlor\UI\Template::getTemplate('header', '1') . "\";");
$current_year = date('Y', time());
$panel_imprint_url = Settings::Get('panel.imprint_url');
if (!empty($panel_imprint_url) && strtolower(substr($panel_imprint_url, 0, 4)) != 'http') {
$panel_imprint_url = 'https://'.$panel_imprint_url;
}
$panel_terms_url = Settings::Get('panel.terms_url');
if (!empty($panel_terms_url) && strtolower(substr($panel_terms_url, 0, 4)) != 'http') {
$panel_terms_url = 'https://'.$panel_terms_url;
}
$panel_privacy_url = Settings::Get('panel.privacy_url');
if (!empty($panel_privacy_url) && strtolower(substr($panel_privacy_url, 0, 4)) != 'http') {
$panel_privacy_url = 'https://'.$panel_privacy_url;
}
eval("\$footer = \"" . \Froxlor\UI\Template::getTemplate('footer', '1') . "\";");
unset($js);

View File

@@ -1080,8 +1080,6 @@ $lng['panel']['unlock'] = 'ontgrendelen';
$lng['question']['customer_reallyunlock'] = 'Weet u zeker dat u klant %s? wilt ontgrendelen';
// ADDED IN FROXLOR 0.9.15-svn1
$lng['serversettings']['perl_server']['title'] = 'Server locatie Perl';
$lng['serversettings']['perl_server']['description'] = 'Standaard is ingesteld op de gids: <a target="blank" href="http://wiki.nginx.org/SimpleCGI">http://wiki.nginx.org/SimpleCGI</a>';
$lng['serversettings']['nginx_php_backend']['title'] = 'Nginx PHP backend';
$lng['serversettings']['nginx_php_backend']['description'] = 'dit is waar het PHP-proces luistert naar verzoeken van nginx, kan een unix socket van ip:poort combinatie zijn';
$lng['serversettings']['phpreload_command']['title'] = 'Commando voor het herladen van PHP';

View File

@@ -60,8 +60,8 @@ $lng['customer']['phone'] = 'Phone';
$lng['customer']['fax'] = 'Fax';
$lng['customer']['email'] = 'Email';
$lng['customer']['customernumber'] = 'Customer ID';
$lng['customer']['diskspace'] = 'Webspace (MiB)';
$lng['customer']['traffic'] = 'Traffic (GiB)';
$lng['customer']['diskspace'] = 'Webspace';
$lng['customer']['traffic'] = 'Traffic';
$lng['customer']['mysqls'] = 'MySQL-databases';
$lng['customer']['emails'] = 'Email-addresses';
$lng['customer']['accounts'] = 'Email-accounts';
@@ -71,6 +71,7 @@ $lng['customer']['subdomains'] = 'Subdomains';
$lng['customer']['domains'] = 'Domains';
$lng['customer']['unlimited'] = '∞';
$lng['customer']['mib'] = 'MiB';
$lng['customer']['gib'] = 'GiB';
/**
* Customermenue
@@ -619,7 +620,7 @@ $lng['traffic']['months'][9] = "September";
$lng['traffic']['months'][10] = "October";
$lng['traffic']['months'][11] = "November";
$lng['traffic']['months'][12] = "December";
$lng['traffic']['mb'] = "Traffic (MiB)";
$lng['traffic']['mb'] = "Traffic";
$lng['traffic']['distribution'] = '<font color="#019522">FTP</font> | <font color="#0000FF">HTTP</font> | <font color="#800000">Mail</font>';
$lng['traffic']['sumhttp'] = 'Total HTTP-Traffic';
$lng['traffic']['sumftp'] = 'Total FTP-Traffic';
@@ -682,7 +683,7 @@ $lng['message']['noreceipients'] = 'No e-mail has been sent because there are no
$lng['admin']['sslsettings'] = 'SSL settings';
$lng['cronjobs']['notyetrun'] = 'Not yet run';
$lng['serversettings']['default_vhostconf']['title'] = 'Default vHost-settings';
$lng['admin']['specialsettings_replacements'] = "You can use the following variables:<br/><code>{DOMAIN}</code>, <code>{DOCROOT}</code>, <code>{CUSTOMER}</code>, <code>{IP}</code>, <code>{PORT}</code>, <code>{SCHEME}</code><br/>";
$lng['admin']['specialsettings_replacements'] = "You can use the following variables:<br/><code>{DOMAIN}</code>, <code>{DOCROOT}</code>, <code>{CUSTOMER}</code>, <code>{IP}</code>, <code>{PORT}</code>, <code>{SCHEME}</code>, <code>{FPMSOCKET}</code> (if applicable)<br/>";
$lng['serversettings']['default_vhostconf']['description'] = 'The content of this field will be included into this ip/port vHost container directly. ' . $lng['admin']['specialsettings_replacements'] . ' Attention: The code won\'t be checked for any errors. If it contains errors, webserver might not start again!';
$lng['serversettings']['apache_globaldiropt']['title'] = 'Directory options for customer-prefix';
$lng['serversettings']['apache_globaldiropt']['description'] = 'The content of this field will be included into the 05_froxlor_dirfix_nofcgid.conf apache config. If empty, the default value is used:<br><br>apache >=2.4<br><code>Require all granted<br>AllowOverride All</code><br><br>apache <=2.2<br><code>Order allow,deny<br>allow from all</code>';
@@ -701,6 +702,8 @@ $lng['dkim']['dkim_dkimkeys']['title'] = 'KeyList filename';
$lng['dkim']['dkim_dkimkeys']['description'] = '<em>Filename</em> of the DKIM KeyList parameter specified in the dkim-milter configuration';
$lng['dkim']['dkimrestart_command']['title'] = 'Milter restart command';
$lng['dkim']['dkimrestart_command']['description'] = 'Please specify the restart command for the DKIM milter service';
$lng['dkim']['privkeysuffix']['title'] = 'Private keys suffix';
$lng['dkim']['privkeysuffix']['description'] = 'You can specify an (optional) filename extension/suffix for the generate dkim private keys. Some services like dkim-filter requires this to be empty';
// ADDED IN 1.2.19-svn9
@@ -805,7 +808,7 @@ $lng['serversettings']['mail_quota_enabled']['enforcelink'] = 'Click here to enf
$lng['question']['admin_quotas_reallywipe'] = 'Do you really want to wipe all quotas on table mail_users? This cannot be reverted!';
$lng['question']['admin_quotas_reallyenforce'] = 'Do you really want to enforce the default quota to all Users? This cannot be reverted!';
$lng['error']['vmailquotawrong'] = 'The quotasize must be positive number.';
$lng['customer']['email_quota'] = 'E-mail quota (MiB)';
$lng['customer']['email_quota'] = 'E-mail quota';
$lng['customer']['email_imap'] = 'E-mail IMAP';
$lng['customer']['email_pop3'] = 'E-mail POP3';
$lng['customer']['mail_quota'] = 'Mailquota';
@@ -1173,8 +1176,8 @@ $lng['panel']['unlock'] = 'Unlock';
$lng['question']['customer_reallyunlock'] = 'Do you really want to unlock customer %s?';
// ADDED IN FROXLOR 0.9.15
$lng['serversettings']['perl_server']['title'] = 'Perl server location';
$lng['serversettings']['perl_server']['description'] = 'Default is set for using the guide found at: <a target="blank" href="http://wiki.nginx.org/SimpleCGI">http://wiki.nginx.org/SimpleCGI</a>';
$lng['serversettings']['perl_server']['title'] = 'Perl server socket location';
$lng['serversettings']['perl_server']['description'] = 'A simple guide can be found at: <a target="blank" href="https://www.nginx.com/resources/wiki/start/topics/examples/fcgiwrap/">nginx.com</a>';
$lng['serversettings']['nginx_php_backend']['title'] = 'Nginx PHP backend';
$lng['serversettings']['nginx_php_backend']['description'] = 'this is where the PHP process is listening for requests from nginx, can be a unix socket of ip:port combination<br />*NOT used with php-fpm';
$lng['serversettings']['phpreload_command']['title'] = 'PHP reload command';
@@ -1540,9 +1543,9 @@ $lng['mysql']['size'] = 'Size';
$lng['error']['invalidhostname'] = 'Hostname needs to be a valid domain. It can\'t be empty nor can it consist only of whitespaces';
$lng['traffic']['http'] = 'HTTP (MiB)';
$lng['traffic']['ftp'] = 'FTP (MiB)';
$lng['traffic']['mail'] = 'Mail (MiB)';
$lng['traffic']['http'] = 'HTTP';
$lng['traffic']['ftp'] = 'FTP';
$lng['traffic']['mail'] = 'Mail';
// ADDED IN 0.9.27-svn1
$lng['serversettings']['mod_fcgid']['idle_timeout']['title'] = 'Idle Timeout';
@@ -1905,6 +1908,7 @@ $lng['error']['dns_mx_needdom'] = 'The MX content value must be a valid domain-n
$lng['error']['dns_mx_noalias'] = 'The MX-content value cannot be an CNAME entry.';
$lng['error']['dns_cname_invaliddom'] = 'Invalid domain-name for CNAME record';
$lng['error']['dns_cname_nomorerr'] = 'There already exists a resource-record with the same record-name. It can not be used as CNAME.';
$lng['error']['dns_other_nomorerr'] = 'There already exists a CNAME record with the same record-name. It can not be used for another type.';
$lng['error']['dns_ns_invaliddom'] = 'Invalid domain-name for NS record';
$lng['error']['dns_srv_prioempty'] = 'Invalid SRV priority given';
$lng['error']['dns_srv_invalidcontent'] = 'Invalid SRV content, must contain of fields weight, port and target, e.g.: 5 5060 sipserver.example.com.';
@@ -2080,7 +2084,7 @@ $lng['serversettings']['default_sslvhostconf']['title'] = 'Default SSL vHost-set
$lng['serversettings']['includedefault_sslvhostconf'] = 'Include non-SSL vHost-settings in SSL-vHost';
$lng['admin']['ownsslvhostsettings'] = 'Own SSL vHost-settings';
$lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Default SSL vHost-settings for every domain container';
$lng['customer']['total_diskspace'] = 'Total diskspace (MiB)';
$lng['customer']['total_diskspace'] = 'Total diskspace';
$lng['admin']['domain_override_tls'] = 'Override system TLS settings';
$lng['domains']['isaliasdomainof'] = 'Is aliasdomain for %s';
$lng['serversettings']['apply_specialsettings_default']['title'] = 'Default value for "' . $lng['admin']['specialsettingsforsubdomains'] . "' setting when editing a domain";
@@ -2100,3 +2104,15 @@ $lng['serversettings']['awstats']['logformat']['title'] = 'LogFormat setting';
$lng['serversettings']['awstats']['logformat']['description'] = 'If you use customized logformat for your webserver, you need change the awstats LogFormat too.<br/>Default is 1. For more information check documentation <a target="_blank" href="https://awstats.sourceforge.io/docs/awstats_config.html#LogFormat">here</a>.';
$lng['error']['cannotdeletesuperadmin'] = 'The first admin cannot be deleted.';
$lng['error']['no_wwwcnamae_ifwwwalias'] = 'Cannot set CNAME record for "www" as domain is set to generate a www-alias. Please change settings to either "No alias" or "Wildcard alias"';
$lng['serversettings']['hide_incompatible_settings'] = 'Hide incompatible settings';
$lng['serversettings']['soaemail'] = 'Mail address to use in SOA records (defaults to sender address from panel settings if empty)';
$lng['imprint'] = 'Legal notes';
$lng['serversettings']['imprint_url']['title'] = 'URL to legal notes / imprint';
$lng['serversettings']['imprint_url']['description'] = 'Specify an URL to your legal notes / imprint site. The link will be visible on the login screen and on the footer when logged in.';
$lng['terms'] = 'Terms of use';
$lng['serversettings']['terms_url']['title'] = 'URL to terms of use';
$lng['serversettings']['terms_url']['description'] = 'Specify an URL to your terms of use site. The link will be visible on the login screen and on the footer when logged in.';
$lng['privacy'] = '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.';

View File

@@ -60,8 +60,8 @@ $lng['customer']['phone'] = 'Telefon';
$lng['customer']['fax'] = 'Fax';
$lng['customer']['email'] = 'E-Mail-Adresse';
$lng['customer']['customernumber'] = 'Kundennummer';
$lng['customer']['diskspace'] = 'Webspace (MiB)';
$lng['customer']['traffic'] = 'Traffic (GiB)';
$lng['customer']['diskspace'] = 'Webspace';
$lng['customer']['traffic'] = 'Traffic';
$lng['customer']['mysqls'] = 'MySQL-Datenbanken';
$lng['customer']['emails'] = 'E-Mail-Adressen';
$lng['customer']['accounts'] = 'E-Mail-Konten';
@@ -612,7 +612,7 @@ $lng['traffic']['months'][9] = "September";
$lng['traffic']['months'][10] = "Oktober";
$lng['traffic']['months'][11] = "November";
$lng['traffic']['months'][12] = "Dezember";
$lng['traffic']['mb'] = "Traffic (MiB)";
$lng['traffic']['mb'] = "Traffic";
$lng['traffic']['day'] = "Tag";
$lng['traffic']['distribution'] = '<span color="#019522">FTP</span> | <span color="#0000FF">HTTP</span> | <span color="#800000">Mail</span>';
$lng['traffic']['sumhttp'] = 'Gesamt HTTP-Traffic';
@@ -676,7 +676,7 @@ $lng['message']['noreceipients'] = 'Es wurde keine E-Mail versendet, da sich kei
$lng['admin']['sslsettings'] = 'SSL-Einstellungen';
$lng['cronjobs']['notyetrun'] = 'Bisher nicht gestartet';
$lng['serversettings']['default_vhostconf']['title'] = 'Standard vHost-Einstellungen';
$lng['admin']['specialsettings_replacements'] = "Die folgenden Variablen können verwendet werden:<br/><code>{DOMAIN}</code>, <code>{DOCROOT}</code>, <code>{CUSTOMER}</code>, <code>{IP}</code>, <code>{PORT}</code>, <code>{SCHEME}</code><br/>";
$lng['admin']['specialsettings_replacements'] = "Die folgenden Variablen können verwendet werden:<br/><code>{DOMAIN}</code>, <code>{DOCROOT}</code>, <code>{CUSTOMER}</code>, <code>{IP}</code>, <code>{PORT}</code>, <code>{SCHEME}</code>, <code>{FPMSOCKET}</code> (wenn zutreffend)<br/>";
$lng['serversettings']['default_vhostconf']['description'] = 'Der Inhalt dieses Feldes wird direkt in den IP/Port-vHost-Container übernommen. ' . $lng['admin']['specialsettings_replacements'] . '<br /><strong>ACHTUNG:</strong> Der Code wird nicht auf Fehler geprüft. Etwaige Fehler werden also auch übernommen. Der Webserver könnte nicht mehr starten!';
$lng['serversettings']['default_vhostconf_domain']['description'] = 'Der Inhalt dieses Feldes wird direkt in jeden Domain-vHost-Container übernommen. ' . $lng['admin']['specialsettings_replacements'] . '<strong>ACHTUNG:</strong> Der Code wird nicht auf Fehler geprüft. Etwaige Fehler werden also auch übernommen. Der Webserver könnte nicht mehr starten!';
$lng['serversettings']['apache_globaldiropt']['title'] = 'Kunden-Prefix Ordner-Optionen';
@@ -695,6 +695,8 @@ $lng['dkim']['dkim_dkimkeys']['title'] = 'KeyList Dateiname';
$lng['dkim']['dkim_dkimkeys']['description'] = 'Dateiname der DKIM-KeyList-Angabe aus der DKIM-Milter-Konfigurationsdatei.';
$lng['dkim']['dkimrestart_command']['title'] = 'Milter-Restart-Kommando';
$lng['dkim']['dkimrestart_command']['description'] = 'Wie lautet das Kommando zum Neustarten des DKIM-Milter-Dienstes?';
$lng['dkim']['privkeysuffix']['title'] = 'Suffix für Private Keys';
$lng['dkim']['privkeysuffix']['description'] = 'Hier kann eine (optionale) Dateiendung für die generierten Private Keys angegeben werden. Manche Dienste, wie dkim-filter, erwarten, dass die Schlüssel keine Dateiendung haben (leer).';
// ADDED IN 1.2.19-svn9
@@ -800,7 +802,7 @@ $lng['serversettings']['mail_quota_enabled']['enforcelink'] = 'Hier klicken, um
$lng['question']['admin_quotas_reallywipe'] = 'Sind Sie sicher, dass alle E-Mail-Kontingente aus der Tabelle mail_users entfernt werden sollen? Dieser Schritt kann nicht rückgängig gemacht werden!';
$lng['question']['admin_quotas_reallyenforce'] = 'Sind Sie sicher, dass Sie allen Benutzern das Default-Quota zuweisen wollen? Dies kann nicht rückgängig gemacht werden!';
$lng['error']['vmailquotawrong'] = 'Die Kontingent-Größe muss positiv sein.';
$lng['customer']['email_quota'] = 'E-Mail-Kontingent (MiB)';
$lng['customer']['email_quota'] = 'E-Mail-Kontingent';
$lng['customer']['email_imap'] = 'IMAP';
$lng['customer']['email_pop3'] = 'POP3';
$lng['customer']['mail_quota'] = 'E-Mail-Kontingent';
@@ -1150,8 +1152,8 @@ $lng['panel']['unlock'] = 'entsperren';
$lng['question']['customer_reallyunlock'] = 'Wollen Sie den Kunden "%s" wirklich entsperren?';
// ADDED IN FROXLOR 0.9.15
$lng['serversettings']['perl_server']['title'] = 'Perl-Server-Ort';
$lng['serversettings']['perl_server']['description'] = 'Der Standardwert ist diesem Guide entnommen: <a target="blank" href="http://wiki.nginx.org/SimpleCGI">http://wiki.nginx.org/SimpleCGI</a>';
$lng['serversettings']['perl_server']['title'] = 'Perl Server-Socket';
$lng['serversettings']['perl_server']['description'] = 'Eine einfache Anleitung hier zu findet man unter <a target="blank" href="http://wiki.nginx.org/SimpleCGIhttps://www.nginx.com/resources/wiki/start/topics/examples/fcgiwrap/">nginx.com</a>';
$lng['serversettings']['nginx_php_backend']['title'] = 'Nginx-PHP-Backend';
$lng['serversettings']['nginx_php_backend']['description'] = 'Dies ist das Backend, auf dem PHP auf Anfragen von Nginx hört. Kann ein UNIX Socket oder eine IP:Port Kombination sein<br />*NICHT relevant bei php-fpm';
$lng['serversettings']['phpreload_command']['title'] = 'PHP-Reload-Befehl';
@@ -1266,9 +1268,9 @@ $lng['mysql']['size'] = 'Datenbankgröße';
$lng['error']['invalidhostname'] = 'Hostname muss eine gültige Domain sein. Er darf weder leer sein noch nur aus Leerzeichen bestehen';
$lng['traffic']['http'] = 'HTTP (MiB)';
$lng['traffic']['ftp'] = 'FTP (MiB)';
$lng['traffic']['mail'] = 'Mail (MiB)';
$lng['traffic']['http'] = 'HTTP';
$lng['traffic']['ftp'] = 'FTP';
$lng['traffic']['mail'] = 'Mail';
// ADDED IN 0.9.27-svn1
$lng['serversettings']['mod_fcgid']['idle_timeout']['title'] = 'Idle-Timeout';
@@ -1556,6 +1558,7 @@ $lng['error']['dns_mx_needdom'] = 'Der Wert des MX Eintrags muss ein gültiger D
$lng['error']['dns_mx_noalias'] = 'Der MX Eintrag darf kein CNAME Eintrag sein.';
$lng['error']['dns_cname_invaliddom'] = 'Ungültiger Domain-Name für CNAME Eintrag';
$lng['error']['dns_cname_nomorerr'] = 'Es existiert bereits ein Eintrag mit dem gleichen Namen. Dieser Eintrag kann daher nicht für CNAME genutzt werden.';
$lng['error']['dns_other_nomorerr'] = 'Es existiert bereits ein CNAME Eintrag mit dem gleichen Namen. Dieser Eintrag kann daher nicht für einen anderen genutzt werden.';
$lng['error']['dns_ns_invaliddom'] = 'Ungültiger Domain-Name für NS Eintrag';
$lng['error']['dns_srv_prioempty'] = 'Ungültige SRV Priorität angegeben';
$lng['error']['dns_srv_invalidcontent'] = 'Ungültiger Wert des SRV Eintrags, dieser muss aus den Feldern weight, port und target, bestehen. Bsp.: 5 5060 sipserver.example.com.';
@@ -1727,7 +1730,7 @@ $lng['serversettings']['default_sslvhostconf']['title'] = 'Standard SSL vHost-Ei
$lng['serversettings']['includedefault_sslvhostconf'] = 'Nicht-SSL vHost-Einstellungen in SSL-vHost inkludieren';
$lng['admin']['ownsslvhostsettings'] = 'Eigene SSL vHost-Einstellungen';
$lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Standard SSL vHost-Einstellungen für jeden Domain-Container';
$lng['customer']['total_diskspace'] = 'Gesamtspeicherplatz (MiB)';
$lng['customer']['total_diskspace'] = 'Gesamtspeicherplatz';
$lng['admin']['domain_override_tls'] = 'Überschreibe System TLS Einstellungen';
$lng['domains']['isaliasdomainof'] = 'Ist Aliasdomain für %s';
$lng['serversettings']['apply_specialsettings_default']['title'] = 'Standardwert für "' . $lng['admin']['specialsettingsforsubdomains'] . "' Einstellung beim Bearbeiten einer Domain";
@@ -1747,3 +1750,15 @@ $lng['serversettings']['awstats']['logformat']['title'] = 'LogFormat Einstellung
$lng['serversettings']['awstats']['logformat']['description'] = 'Wenn ein benutzerdefiniertes LogFormat beim Webserver verwendet wird, muss LogFormat von awstats ebenso angepasst werden.<br/>Standard ist 1. Für weitere Informationen siehe Dokumentation unter <a target="_blank" href="https://awstats.sourceforge.io/docs/awstats_config.html#LogFormat">hier</a>.';
$lng['error']['cannotdeletesuperadmin'] = 'Der erste Administrator kann nicht gelöscht werden.';
$lng['error']['no_wwwcnamae_ifwwwalias'] = 'Es kann kein CNAME Eintrag für "www" angelegt werden, da die Domain einen www-Alias aktiviert hat. Ändere diese Einstellung auf "Kein Alias" oder "Wildcard Alias"';
$lng['serversettings']['hide_incompatible_settings'] = 'Inkompatible Einstellungen ausblenden';
$lng['serversettings']['soaemail'] = 'Mail-Adresse für SOA-Einträge (verwendet Panel-Absender-Name der Panel-Einstellungen falls leer)';
$lng['imprint'] = 'Impressum';
$lng['serversettings']['imprint_url']['title'] = 'URL zum Impressum';
$lng['serversettings']['imprint_url']['description'] = 'Die URL zur Impressums-Seite. Der Link ist auf der Login-Seite und wenn eingeloggt, in der Fußzeile sichtbar.';
$lng['terms'] = 'AGB';
$lng['serversettings']['terms_url']['title'] = 'URL zu den AGB';
$lng['serversettings']['terms_url']['description'] = 'Die URL zur AGB-Seite. Der Link ist auf der Login-Seite und wenn eingeloggt, in der Fußzeile sichtbar.';
$lng['privacy'] = '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.';

View File

@@ -1107,9 +1107,6 @@ $lng['panel']['unlock'] = 'unlock';
$lng['question']['customer_reallyunlock'] = 'Sei sicuro di voler sbloccare il cliente %s?';
// ADDED IN FROXLOR 0.9.15-svn1
$lng['serversettings']['perl_server']['title'] = 'Localizzazione del server Perl';
$lng['serversettings']['perl_server']['description'] = 'Di default è impostato per utilizzare la guida disponibile sul sito: <a target="blank" href="http://wiki.nginx.org/SimpleCGI">http://wiki.nginx.org/SimpleCGI</a>';
$lng['serversettings']['nginx_php_backend']['title'] = 'Nginx PHP backend';
$lng['serversettings']['nginx_php_backend']['description'] = 'questo è dove in ascolto il processo PHP per le richieste da nginx, può essere un socket unix combinazione IP:Porta';
$lng['serversettings']['phpreload_command']['title'] = 'Comando riavvio PHP';

View File

@@ -34,7 +34,7 @@
<if $row['letsencrypt'] == '1'>
&nbsp;<img src="templates/{$theme}/assets/img/icons/ssl_letsencrypt.png" alt="{$lng['panel']['letsencrypt']}" title="{$lng['panel']['letsencrypt']}" />
</if>
<if !(isset($row['domainaliasid']) && $row['domainaliasid'] != 0) && $row['id'] != \Froxlor\Settings::Get('system.hostname_id')>
<if !(isset($row['domainaliasid']) && !empty($row['domainaliasid'])) && $row['id'] != \Froxlor\Settings::Get('system.hostname_id')>
<if !(isset($row['standardsubdomain']) && $row['standardsubdomain'] == $row['id'])>
&nbsp;<a href="{$linker->getLink(array('section' => 'domains', 'page' => $page, 'action' => 'delete', 'id' => $row['id']))}">
<img src="templates/{$theme}/assets/img/icons/delete.png" alt="{$lng['panel']['delete']}" title="{$lng['panel']['delete']}" />

View File

@@ -45,7 +45,7 @@ $header
</div>
<div class="canvasbox">
<input type="hidden" id="diskspace" class="circular" data-used="{$overview['diskspace_used']}" data-available="{$userinfo['diskspace']}" data-assigned="{$userinfo['diskspace_used']}">
<input type="hidden" id="diskspace" class="circular" data-used="{$overview['diskspace_bytes_used']}" data-available="{$userinfo['diskspace_bytes']}" data-assigned="{$userinfo['diskspace_bytes_used']}">
<canvas id="diskspace-canvas" width="120" height="76"></canvas><br/>
{$lng['customer']['diskspace']}<br />
<small>
@@ -58,7 +58,7 @@ $header
</div>
<div class="canvasbox">
<input type="hidden" id="traffic" class="circular" data-used="{$overview['traffic_used']}" data-available="{$userinfo['traffic']}" data-assigned="{$userinfo['traffic_used']}">
<input type="hidden" id="traffic" class="circular" data-used="{$overview['traffic_bytes_used']}" data-available="{$userinfo['traffic_bytes']}" data-assigned="{$userinfo['traffic_bytes_used']}">
<canvas id="traffic-canvas" width="120" height="76"></canvas><br/>
{$lng['customer']['traffic']}<br />
<small>

View File

@@ -1737,4 +1737,11 @@ td.size-50 {
font-weight: 700;
padding: 5px 10px;
color: #ffe !important;
}
}
.footer-link:after {
content: " |";
}
.footer-link:last-child:after {
content: "";
}

View File

@@ -15,7 +15,7 @@
</td>
<td>
<if $row['aliasdomain'] == ''>{$row['documentroot']}</if>
<if isset($row['aliasdomainid']) && $row['aliasdomainid'] != 0>{$lng['domains']['aliasdomain']} {$row['aliasdomain']}</if>
<if isset($row['aliasdomainid']) && !empty($row['aliasdomainid'])>{$lng['domains']['aliasdomain']} {$row['aliasdomain']}</if>
</td>
<td>
<if $row['caneditdomain'] == '1'>
@@ -28,7 +28,7 @@
<img src="templates/{$theme}/assets/img/icons/view.png" alt="{$lng['panel']['viewlogs']}" title="{$lng['panel']['viewlogs']}" />
</a>
</if>
<if $row['parentdomainid'] != '0' && !(isset($row['domainaliasid']) && $row['domainaliasid'] != 0)>
<if $row['parentdomainid'] != '0' && (!isset($row['domainaliasid']) || empty($row['domainaliasid']))>
<a href="{$linker->getLink(array('section' => 'domains', 'page' => 'domains', 'action' => 'delete', 'id' => $row['id']))}">
<img src="templates/{$theme}/assets/img/icons/delete.png" alt="{$lng['panel']['delete']}" title="{$lng['panel']['delete']}" />
</a>&nbsp;
@@ -46,10 +46,10 @@
<if $row['letsencrypt'] == '1'>
<img src="templates/{$theme}/assets/img/icons/ssl_letsencrypt.png" alt="{$lng['panel']['letsencrypt']}" title="{$lng['panel']['letsencrypt']}" />
</if>
<if $row['parentdomainid'] == '0' && !(isset($row['domainaliasid']) && $row['domainaliasid'] != 0)>
<if $row['parentdomainid'] == '0' && (!isset($row['domainaliasid']) || empty($row['domainaliasid']))>
({$lng['domains']['isassigneddomain']})&nbsp;
</if>
<if isset($row['domainaliasid']) && $row['domainaliasid'] != 0>
<if isset($row['domainaliasid']) && !empty($row['domainaliasid'])>
<a href="{$linker->getLink(array('section' => 'domains', 'page' => 'domains', 'searchfield' => 'd.aliasdomain', 'searchtext' => $row['id']))}">{$lng['domains']['hasaliasdomains']}</a>
</if>
</td>

View File

@@ -9,7 +9,7 @@ $header
<div class="grid-u-1-2" id="statsbox">
<if $userinfo['diskspace'] != '0'>
<div class="canvasbox">
<input type="hidden" id="totalspace" class="circular" data-used="{$userinfo['total_used']}" data-available="{$userinfo['diskspace']}">
<input type="hidden" id="totalspace" class="circular" data-used="{$userinfo['total_bytes_used']}" data-available="{$userinfo['diskspace_bytes']}">
<canvas id="totalspace-canvas" width="120" height="76"></canvas><br />
{$lng['customer']['total_diskspace']}<br />
<small>
@@ -37,7 +37,7 @@ $header
<if $userinfo['diskspace'] != '0'>
<div class="canvasbox">
<input type="hidden" id="diskspace" class="circular" data-used="{$userinfo['diskspace_used']}" data-available="{$userinfo['diskspace']}">
<input type="hidden" id="diskspace" class="circular" data-used="{$userinfo['diskspace_bytes_used']}" data-available="{$userinfo['diskspace_bytes']}">
<canvas id="diskspace-canvas" width="120" height="76"></canvas><br />
{$lng['customer']['diskspace']}<br />
<small>
@@ -51,7 +51,7 @@ $header
<if $userinfo['traffic'] != '0'>
<div class="canvasbox">
<input type="hidden" id="traffic" class="circular" data-used="{$userinfo['traffic_used']}" data-available="{$userinfo['traffic']}">
<input type="hidden" id="traffic" class="circular" data-used="{$userinfo['traffic_bytes_used']}" data-available="{$userinfo['traffic_bytes']}">
<canvas id="traffic-canvas" width="120" height="76"></canvas><br />
{$lng['customer']['traffic']}<br />
<small>
@@ -87,7 +87,7 @@ $header
<if $userinfo['email_accounts'] != '∞'>
{$userinfo['email_accounts']} {$lng['panel']['available']}<br />
</if>
{$userinfo['mailspace_used']} {$lng['customer']['mib']}
{$userinfo['mailspace_used']}
</small>
</div>
</if>
@@ -130,7 +130,7 @@ $header
<if $userinfo['mysqls'] != '∞'>
{$userinfo['mysqls']} {$lng['panel']['available']}<br />
</if>
{$userinfo['dbspace_used']} {$lng['customer']['mib']}
{$userinfo['dbspace_used']}
</small>
</div>
</if>

View File

@@ -4,11 +4,14 @@
</div>
</if>
<footer>
<span><img src="templates/{$theme}/assets/img/logo_grey.png" alt="Froxlor" />
<span><img src="templates/{$theme}/assets/img/logo_grey.png" alt="Froxlor" />
<if (\Froxlor\Settings::Get('admin.show_version_login') == '1' && $filename == 'index.php') || ($filename != 'index.php' && \Froxlor\Settings::Get('admin.show_version_footer') == '1')>
{$version}{$branding}
</if>
&copy; 2009-{$current_year} by <a href="http://www.froxlor.org/" rel="external">the Froxlor Team</a><br />
<if (\Froxlor\Settings::Get('panel.imprint_url')) != ''><a href="{$panel_imprint_url}" target="_blank" class="footer-link">{$lng['imprint']}</a></if>
<if (\Froxlor\Settings::Get('panel.terms_url')) != ''><a href="{$panel_terms_url}" target="_blank" class="footer-link">{$lng['terms']}</a></if>
<if (\Froxlor\Settings::Get('panel.privacy_url')) != ''><a href="{$panel_privacy_url}" target="_blank" class="footer-link">{$lng['privacy']}</a></if>
</span>
<if $lng['translator'] != ''>
<br /><span>{$lng['panel']['translator']}: {$lng['translator']}

View File

@@ -115,6 +115,14 @@ class CustomersTest extends TestCase
$json_result = Customers::getLocal($admin_userdata)->listing();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']);
$this->assertFalse(isset($result['list'][0]['webspace_used']));
$json_result = Customers::getLocal($admin_userdata, [
'show_usages' => true
])->listing();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']);
$this->assertTrue(isset($result['list'][0]['webspace_used']));
$json_result = Customers::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];

View File

@@ -101,6 +101,7 @@ class DomainZonesTest extends TestCase
}
/**
*
* @depends testCustomerDomainZonesAddA
*/
public function testAdminDomainZonesListing()
@@ -303,14 +304,14 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$json_result = DomainZones::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
$this->assertTrue(count($result) > 1);
$found = false;
foreach ($result as $entry) {
if (substr($entry, -strlen($content)) == $content) {
if (substr($entry, - strlen($content)) == $content) {
$found = true;
break;
}
@@ -328,7 +329,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$json_result = DomainZones::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
@@ -341,7 +342,7 @@ class DomainZonesTest extends TestCase
}
}
$this->assertTrue($found);
$this->assertEquals('@ 18000 IN CAA '.$content, $entry);
$this->assertEquals('@ 18000 IN CAA ' . $content, $entry);
}
public function testAdminDomainZonesAddCAAIssueWithTwoParameters()
@@ -353,7 +354,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$json_result = DomainZones::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
@@ -366,7 +367,7 @@ class DomainZonesTest extends TestCase
}
}
$this->assertTrue($found);
$this->assertEquals('@ 18000 IN CAA '.$content, $entry);
$this->assertEquals('@ 18000 IN CAA ' . $content, $entry);
}
public function testAdminDomainZonesAddCAAInvalidIssueValue()
@@ -378,7 +379,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$this->expectExceptionMessage("DNS content invalid");
DomainZones::getLocal($admin_userdata, $data)->add();
@@ -393,7 +394,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$this->expectExceptionMessage("DNS content invalid");
DomainZones::getLocal($admin_userdata, $data)->add();
@@ -408,7 +409,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$this->expectExceptionMessage("DNS content invalid");
DomainZones::getLocal($admin_userdata, $data)->add();
@@ -423,7 +424,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$json_result = DomainZones::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
@@ -436,7 +437,7 @@ class DomainZonesTest extends TestCase
}
}
$this->assertTrue($found);
$this->assertEquals('@ 18000 IN CAA '.$content, $entry);
$this->assertEquals('@ 18000 IN CAA ' . $content, $entry);
}
public function testAdminDomainZonesAddCAAIssueWildWithParameters()
@@ -448,7 +449,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$json_result = DomainZones::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
@@ -461,7 +462,7 @@ class DomainZonesTest extends TestCase
}
}
$this->assertTrue($found);
$this->assertEquals('@ 18000 IN CAA '.$content, $entry);
$this->assertEquals('@ 18000 IN CAA ' . $content, $entry);
}
public function testAdminDomainZonesAddCAAIssueWildWithTwoParameters()
@@ -473,7 +474,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$json_result = DomainZones::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
@@ -486,7 +487,7 @@ class DomainZonesTest extends TestCase
}
}
$this->assertTrue($found);
$this->assertEquals('@ 18000 IN CAA '.$content, $entry);
$this->assertEquals('@ 18000 IN CAA ' . $content, $entry);
}
public function testAdminDomainZonesAddCAAInvalidIssueWildValue()
@@ -498,7 +499,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$this->expectExceptionMessage("DNS content invalid");
DomainZones::getLocal($admin_userdata, $data)->add();
@@ -513,7 +514,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$this->expectExceptionMessage("DNS content invalid");
DomainZones::getLocal($admin_userdata, $data)->add();
@@ -528,7 +529,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$this->expectExceptionMessage("DNS content invalid");
DomainZones::getLocal($admin_userdata, $data)->add();
@@ -543,7 +544,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$json_result = DomainZones::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
@@ -556,7 +557,7 @@ class DomainZonesTest extends TestCase
}
}
$this->assertTrue($found);
$this->assertEquals('@ 18000 IN CAA '.$content, $entry);
$this->assertEquals('@ 18000 IN CAA ' . $content, $entry);
}
public function testAdminDomainZonesAddCAAIodefMailInvalid()
@@ -568,7 +569,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$this->expectExceptionMessage("DNS content invalid");
DomainZones::getLocal($admin_userdata, $data)->add();
@@ -583,7 +584,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$json_result = DomainZones::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
@@ -596,7 +597,7 @@ class DomainZonesTest extends TestCase
}
}
$this->assertTrue($found);
$this->assertEquals('@ 18000 IN CAA '.$content, $entry);
$this->assertEquals('@ 18000 IN CAA ' . $content, $entry);
}
public function testAdminDomainZonesAddCAAIodefHttpInvalid()
@@ -608,7 +609,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$this->expectExceptionMessage("DNS content invalid");
DomainZones::getLocal($admin_userdata, $data)->add();
@@ -623,7 +624,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$json_result = DomainZones::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
@@ -636,7 +637,7 @@ class DomainZonesTest extends TestCase
}
}
$this->assertTrue($found);
$this->assertEquals('@ 18000 IN CAA '.$content, $entry);
$this->assertEquals('@ 18000 IN CAA ' . $content, $entry);
}
public function testAdminDomainZonesAddCAAIodefHttpsInvalid()
@@ -648,7 +649,7 @@ class DomainZonesTest extends TestCase
'domainname' => 'test2.local',
'record' => '@',
'type' => 'CAA',
'content' => $content,
'content' => $content
];
$this->expectExceptionMessage("DNS content invalid");
DomainZones::getLocal($admin_userdata, $data)->add();
@@ -745,6 +746,38 @@ class DomainZonesTest extends TestCase
DomainZones::getLocal($admin_userdata, $data)->add();
}
/**
*
* @depends testAdminDomainZonesAddCname
*/
public function testAdminDomainZonesAddForExistingCname()
{
global $admin_userdata;
// set domain to www-alias
$data = [
'domainname' => 'test2.local',
'selectserveralias' => '1'
];
Domains::getLocal($admin_userdata, $data)->update();
foreach ([
'A' => '127.0.0.1',
'AAAA' => '::1',
'MX' => 'mail.example.com.',
'NS' => 'ns.example.com.'
] as $type => $val) {
$data = [
'domainname' => 'test2.local',
'record' => 'db',
'type' => $type,
'content' => $val
];
$this->expectExceptionMessage('There already exists a CNAME record with the same record-name. It can not be used for another type.');
DomainZones::getLocal($admin_userdata, $data)->add();
}
}
/**
*
* @depends testAdminDomainZonesAddCname

View File

@@ -32,13 +32,15 @@ class DomainsTest extends TestCase
'ssl_protocols' => array(
'TLSv1.2',
'TLSv1.3'
)
),
'description' => 'awesome domain'
];
$json_result = Domains::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
$this->assertEquals($customer_userdata['documentroot'] . 'test.local/', $result['documentroot']);
$this->assertTrue(in_array('TLSv1.3', explode(",", $result['ssl_protocols'])));
$this->assertEquals('0', $result['isemaildomain']);
$this->assertEquals('awesome domain', $result['description']);
}
/**
@@ -207,7 +209,8 @@ class DomainsTest extends TestCase
'domainname' => 'test.local',
'email_only' => 1,
'override_tls' => 0,
'documentroot' => 'web'
'documentroot' => 'web',
'description' => 'changed desc'
];
$json_result = Domains::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
@@ -215,6 +218,7 @@ class DomainsTest extends TestCase
$this->assertFalse(in_array('TLSv1.3', explode(",", $result['ssl_protocols'])));
$this->assertEquals('test.local', $result['domain']);
$this->assertEquals($customer_userdata['documentroot'] . 'web/', $result['documentroot']);
$this->assertEquals('changed desc', $result['description']);
}
/**

View File

@@ -36,12 +36,14 @@ class MailsTest extends TestCase
$data = [
'email_part' => 'info',
'domain' => 'test2.local'
'domain' => 'test2.local',
'description' => 'awesome email'
];
$json_result = Emails::getLocal($customer_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
$this->assertEquals("info@test2.local", $result['email_full']);
$this->assertEquals(0, $result['iscatchall']);
$this->assertEquals('awesome email', $result['description']);
// reset setting
Settings::Set('panel.customer_hide_options', '', true);
@@ -87,11 +89,13 @@ class MailsTest extends TestCase
$data = [
'emailaddr' => 'catchall@test2.local',
'iscatchall' => 1
'iscatchall' => 1,
'description' => 'now with catchall'
];
$json_result = Emails::getLocal($customer_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['iscatchall']);
$this->assertEquals('now with catchall', $result['description']);
}
public function testCustomerEmailForwardersAdd()
@@ -444,6 +448,36 @@ class MailsTest extends TestCase
$this->assertEquals(0, $result['quota']);
}
public function testAdminEmailAccountsUpdateDeactivated()
{
global $admin_userdata;
// disable
$data = [
'emailaddr' => 'info@test2.local',
'loginname' => 'test1',
'deactivated' => 1
];
$json_result = EmailAccounts::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
// quota is disabled
$this->assertEquals(0, $result['imap']);
$this->assertEquals(0, $result['pop3']);
$this->assertEquals('N', $result['postfix']);
// re-enable
$data = [
'emailaddr' => 'info@test2.local',
'loginname' => 'test1',
'deactivated' => 0
];
$json_result = EmailAccounts::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
// quota is disabled
$this->assertEquals(1, $result['imap']);
$this->assertEquals(1, $result['pop3']);
$this->assertEquals('Y', $result['postfix']);
}
public function testAdminEmailAccountsUndefinedGet()
{
global $admin_userdata;