Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fd89c48e8 | ||
|
|
eceb144a77 | ||
|
|
1d9651b18a | ||
|
|
49db4e60cb | ||
|
|
53e8ccbccb | ||
|
|
6d8fc215f1 | ||
|
|
f94c303cb3 | ||
|
|
2be1873354 | ||
|
|
d1d36c32fe | ||
|
|
3b3527348f | ||
|
|
036d5f0713 | ||
|
|
a1b8807b0f | ||
|
|
356a087b6a | ||
|
|
0a77fd7150 | ||
|
|
67d67a287f | ||
|
|
1f792466bf | ||
|
|
5a6343b47c | ||
|
|
841c529107 | ||
|
|
41c3f21f0b | ||
|
|
b8c0688ba0 |
@@ -132,6 +132,16 @@ return array(
|
|||||||
'int_min' => 3600, /* 1 hour */
|
'int_min' => 3600, /* 1 hour */
|
||||||
'int_max' => 2147483647, /* integer max */
|
'int_max' => 2147483647, /* integer max */
|
||||||
'save_method' => 'storeSettingField'
|
'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'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -56,6 +56,26 @@ if ($page == 'overview' || $page == 'customers') {
|
|||||||
$maxyears = date("Y") - $minyear['year'];
|
$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 ++) {
|
for ($years = 0; $years <= $maxyears; $years ++) {
|
||||||
|
|
||||||
$overview['year'] = date("Y") - $years;
|
$overview['year'] = date("Y") - $years;
|
||||||
@@ -76,14 +96,7 @@ if ($page == 'overview' || $page == 'customers') {
|
|||||||
'dec' => 0
|
'dec' => 0
|
||||||
);
|
);
|
||||||
|
|
||||||
$customer_name_list_stmt = Database::prepare("
|
Database::pexecute($customer_name_list_stmt, $params);
|
||||||
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']
|
|
||||||
));
|
|
||||||
|
|
||||||
while ($customer_name = $customer_name_list_stmt->fetch(PDO::FETCH_ASSOC)) {
|
while ($customer_name = $customer_name_list_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||||
|
|
||||||
@@ -104,11 +117,6 @@ if ($page == 'overview' || $page == 'customers') {
|
|||||||
'dec' => '-'
|
'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(
|
Database::pexecute($traffic_list_stmt, array(
|
||||||
'year' => (date("Y") - $years),
|
'year' => (date("Y") - $years),
|
||||||
'id' => $customer_name['customerid']
|
'id' => $customer_name['customerid']
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ if ($action == '2fa_entercode') {
|
|||||||
));
|
));
|
||||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
if ($row['customer'] == $loginname) {
|
if ($row && $row['customer'] == $loginname) {
|
||||||
$table = "`" . TABLE_PANEL_CUSTOMERS . "`";
|
$table = "`" . TABLE_PANEL_CUSTOMERS . "`";
|
||||||
$uid = 'customerid';
|
$uid = 'customerid';
|
||||||
$adminsession = '0';
|
$adminsession = '0';
|
||||||
@@ -142,7 +142,7 @@ if ($action == '2fa_entercode') {
|
|||||||
"loginname" => $loginname
|
"loginname" => $loginname
|
||||||
));
|
));
|
||||||
$row3 = $stmt->fetch(PDO::FETCH_ASSOC);
|
$row3 = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
if ($row3['customer'] == $loginname) {
|
if ($row3 && $row3['customer'] == $loginname) {
|
||||||
$table = "`" . TABLE_PANEL_CUSTOMERS . "`";
|
$table = "`" . TABLE_PANEL_CUSTOMERS . "`";
|
||||||
$uid = 'customerid';
|
$uid = 'customerid';
|
||||||
$adminsession = '0';
|
$adminsession = '0';
|
||||||
@@ -181,7 +181,7 @@ if ($action == '2fa_entercode') {
|
|||||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($row['admin'] == $loginname) {
|
if ($row && $row['admin'] == $loginname) {
|
||||||
$table = "`" . TABLE_PANEL_ADMINS . "`";
|
$table = "`" . TABLE_PANEL_ADMINS . "`";
|
||||||
$uid = 'adminid';
|
$uid = 'adminid';
|
||||||
$adminsession = '1';
|
$adminsession = '1';
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ CREATE TABLE `mail_virtual` (
|
|||||||
`customerid` int(11) NOT NULL default '0',
|
`customerid` int(11) NOT NULL default '0',
|
||||||
`popaccountid` int(11) NOT NULL default '0',
|
`popaccountid` int(11) NOT NULL default '0',
|
||||||
`iscatchall` tinyint(1) unsigned NOT NULL default '0',
|
`iscatchall` tinyint(1) unsigned NOT NULL default '0',
|
||||||
|
`description` varchar(255) NOT NULL DEFAULT '',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `email` (`email`)
|
KEY `email` (`email`)
|
||||||
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
|
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||||
@@ -275,6 +276,7 @@ CREATE TABLE `panel_domains` (
|
|||||||
`ssl_enabled` tinyint(1) DEFAULT '1',
|
`ssl_enabled` tinyint(1) DEFAULT '1',
|
||||||
`ssl_honorcipherorder` tinyint(1) DEFAULT '0',
|
`ssl_honorcipherorder` tinyint(1) DEFAULT '0',
|
||||||
`ssl_sessiontickets` tinyint(1) DEFAULT '1',
|
`ssl_sessiontickets` tinyint(1) DEFAULT '1',
|
||||||
|
`description` varchar(255) NOT NULL DEFAULT '',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `customerid` (`customerid`),
|
KEY `customerid` (`customerid`),
|
||||||
KEY `parentdomain` (`parentdomainid`),
|
KEY `parentdomain` (`parentdomainid`),
|
||||||
@@ -674,6 +676,7 @@ opcache.interned_strings_buffer'),
|
|||||||
('system', 'apply_phpconfigs_default', '1'),
|
('system', 'apply_phpconfigs_default', '1'),
|
||||||
('system', 'hide_incompatible_settings', '0'),
|
('system', 'hide_incompatible_settings', '0'),
|
||||||
('system', 'include_default_vhostconf', '0'),
|
('system', 'include_default_vhostconf', '0'),
|
||||||
|
('system', 'soaemail', ''),
|
||||||
('api', 'enabled', '0'),
|
('api', 'enabled', '0'),
|
||||||
('2fa', 'enabled', '1'),
|
('2fa', 'enabled', '1'),
|
||||||
('panel', 'decimal_places', '4'),
|
('panel', 'decimal_places', '4'),
|
||||||
@@ -708,8 +711,8 @@ opcache.interned_strings_buffer'),
|
|||||||
('panel', 'password_special_char', '!?<>§$%+#=@'),
|
('panel', 'password_special_char', '!?<>§$%+#=@'),
|
||||||
('panel', 'customer_hide_options', ''),
|
('panel', 'customer_hide_options', ''),
|
||||||
('panel', 'is_configured', '0'),
|
('panel', 'is_configured', '0'),
|
||||||
('panel', 'version', '0.10.24'),
|
('panel', 'version', '0.10.25'),
|
||||||
('panel', 'db_version', '202101200');
|
('panel', 'db_version', '202103030');
|
||||||
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `panel_tasks`;
|
DROP TABLE IF EXISTS `panel_tasks`;
|
||||||
|
|||||||
@@ -725,3 +725,27 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.23.1')) {
|
|||||||
showUpdateStep("Updating from 0.10.23.1 to 0.10.24", false);
|
showUpdateStep("Updating from 0.10.23.1 to 0.10.24", false);
|
||||||
\Froxlor\Froxlor::updateToVersion('0.10.24');
|
\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');
|
||||||
|
}
|
||||||
|
|
||||||
|
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');
|
||||||
|
}
|
||||||
|
|||||||
@@ -310,6 +310,13 @@ abstract class ApiCommand extends ApiParameter
|
|||||||
} elseif (in_array($valoper['op'], $ops)) {
|
} elseif (in_array($valoper['op'], $ops)) {
|
||||||
$condition .= $field . ' ' . $valoper['op'] . ':' . $cleanfield;
|
$condition .= $field . ' ' . $valoper['op'] . ':' . $cleanfield;
|
||||||
$query_fields[':' . $cleanfield] = $valoper['value'] ?? '';
|
$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 {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -518,7 +525,7 @@ abstract class ApiCommand extends ApiParameter
|
|||||||
$customer_ids[] = $customer['customerid'];
|
$customer_ids[] = $customer['customerid'];
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
throw new \Exception("You cannot access this resource", 405);
|
||||||
}
|
}
|
||||||
$customer_ids = array(
|
$customer_ids = array(
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
|||||||
* optional specify offset for resultset
|
* optional specify offset for resultset
|
||||||
* @param array $sql_orderby
|
* @param array $sql_orderby
|
||||||
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
|
* 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
|
* @access admin
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
@@ -41,6 +43,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
|||||||
public function listing()
|
public function listing()
|
||||||
{
|
{
|
||||||
if ($this->isAdmin()) {
|
if ($this->isAdmin()) {
|
||||||
|
$show_usages = $this->getBoolParam('show_usages', true, false);
|
||||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list customers");
|
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list customers");
|
||||||
$query_fields = array();
|
$query_fields = array();
|
||||||
$result_stmt = Database::prepare("
|
$result_stmt = Database::prepare("
|
||||||
@@ -57,7 +60,47 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
|||||||
$params = array_merge($params, $query_fields);
|
$params = array_merge($params, $query_fields);
|
||||||
Database::pexecute($result_stmt, $params, true, true);
|
Database::pexecute($result_stmt, $params, true, true);
|
||||||
$result = array();
|
$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)) {
|
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;
|
$result[] = $row;
|
||||||
}
|
}
|
||||||
return $this->response(200, "successful", array(
|
return $this->response(200, "successful", array(
|
||||||
@@ -103,6 +146,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
|||||||
* optional, the customer-id
|
* optional, the customer-id
|
||||||
* @param string $loginname
|
* @param string $loginname
|
||||||
* optional, the loginname
|
* optional, the loginname
|
||||||
|
* @param bool $show_usages
|
||||||
|
* optional, default false
|
||||||
*
|
*
|
||||||
* @access admin, customer
|
* @access admin, customer
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
@@ -113,6 +158,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
|||||||
$id = $this->getParam('id', true, 0);
|
$id = $this->getParam('id', true, 0);
|
||||||
$ln_optional = ($id <= 0 ? false : true);
|
$ln_optional = ($id <= 0 ? false : true);
|
||||||
$loginname = $this->getParam('loginname', $ln_optional, '');
|
$loginname = $this->getParam('loginname', $ln_optional, '');
|
||||||
|
$show_usages = $this->getBoolParam('show_usages', true, false);
|
||||||
|
|
||||||
if ($this->isAdmin()) {
|
if ($this->isAdmin()) {
|
||||||
$result_stmt = Database::prepare("
|
$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) {
|
if (! $this->isAdmin() && $result['custom_notes_show'] != 1) {
|
||||||
$result['custom_notes'] = "";
|
$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'] . "'");
|
$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);
|
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']));
|
$email = $this->getParam('email', true, $idna_convert->decode($result['email']));
|
||||||
$name = $this->getParam('name', true, $result['name']);
|
$name = $this->getParam('name', true, $result['name']);
|
||||||
$firstname = $this->getParam('firstname', true, $result['firstname']);
|
$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']);
|
$company = $this->getParam('company', ($company_required ? false : true), $result['company']);
|
||||||
$street = $this->getParam('street', true, $result['street']);
|
$street = $this->getParam('street', true, $result['street']);
|
||||||
$zipcode = $this->getParam('zipcode', true, $result['zipcode']);
|
$zipcode = $this->getParam('zipcode', true, $result['zipcode']);
|
||||||
@@ -1411,7 +1491,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
|||||||
), true, true);
|
), true, true);
|
||||||
|
|
||||||
// first gather all domain-id's to clean up panel_domaintoip, dns-entries and certificates accordingly
|
// 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(
|
Database::pexecute($did_stmt, array(
|
||||||
'id' => $id
|
'id' => $id
|
||||||
), true, true);
|
), true, true);
|
||||||
@@ -1431,6 +1511,10 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
|||||||
Database::pexecute($stmt, array(
|
Database::pexecute($stmt, array(
|
||||||
'did' => $row['id']
|
'did' => $row['id']
|
||||||
), true, true);
|
), 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
|
// remove customer domains
|
||||||
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");
|
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");
|
||||||
|
|||||||
@@ -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
|
* 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
|
* @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
|
* 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
|
* @access admin
|
||||||
* @throws \Exception
|
* @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'));
|
$tlsv13_cipher_list = $this->getParam('tlsv13_cipher_list', true, Settings::Get('system.tlsv13_cipher_list'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$description = $this->getParam('description', true, '');
|
||||||
|
|
||||||
// validation
|
// validation
|
||||||
$p_domain = strtolower($p_domain);
|
$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,
|
'tlsv13_cipher_list' => $tlsv13_cipher_list,
|
||||||
'sslenabled' => $sslenabled,
|
'sslenabled' => $sslenabled,
|
||||||
'honorcipherorder' => $honorcipherorder,
|
'honorcipherorder' => $honorcipherorder,
|
||||||
'sessiontickets' => $sessiontickets
|
'sessiontickets' => $sessiontickets,
|
||||||
|
'description' => $description
|
||||||
);
|
);
|
||||||
|
|
||||||
$ins_stmt = Database::prepare("
|
$ins_stmt = Database::prepare("
|
||||||
@@ -780,7 +784,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
`tlsv13_cipher_list` = :tlsv13_cipher_list,
|
`tlsv13_cipher_list` = :tlsv13_cipher_list,
|
||||||
`ssl_enabled` = :sslenabled,
|
`ssl_enabled` = :sslenabled,
|
||||||
`ssl_honorcipherorder` = :honorcipherorder,
|
`ssl_honorcipherorder` = :honorcipherorder,
|
||||||
`ssl_sessiontickets`= :sessiontickets
|
`ssl_sessiontickets` = :sessiontickets,
|
||||||
|
`description` = :description
|
||||||
");
|
");
|
||||||
Database::pexecute($ins_stmt, $ins_data, true, true);
|
Database::pexecute($ins_stmt, $ins_data, true, true);
|
||||||
$domainid = Database::lastInsertId();
|
$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
|
* optional whether to honor the (server) cipher order for this domain. default 0 (false), requires SSL
|
||||||
* @param bool $sessiontickets
|
* @param bool $sessiontickets
|
||||||
* optional whether to enable or disable TLS sessiontickets (RFC 5077) for this domain. default 1 (true), requires SSL
|
* 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
|
* @access admin
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
@@ -1027,6 +1034,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
$ssl_cipher_list = $result['ssl_cipher_list'];
|
$ssl_cipher_list = $result['ssl_cipher_list'];
|
||||||
$tlsv13_cipher_list = $result['tlsv13_cipher_list'];
|
$tlsv13_cipher_list = $result['tlsv13_cipher_list'];
|
||||||
}
|
}
|
||||||
|
$description = $this->getParam('description', true, $result['description']);
|
||||||
|
|
||||||
// count subdomain usage of source-domain
|
// count subdomain usage of source-domain
|
||||||
$subdomains_stmt = Database::prepare("
|
$subdomains_stmt = Database::prepare("
|
||||||
@@ -1589,6 +1597,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
$update_data['sslenabled'] = $sslenabled;
|
$update_data['sslenabled'] = $sslenabled;
|
||||||
$update_data['honorcipherorder'] = $honorcipherorder;
|
$update_data['honorcipherorder'] = $honorcipherorder;
|
||||||
$update_data['sessiontickets'] = $sessiontickets;
|
$update_data['sessiontickets'] = $sessiontickets;
|
||||||
|
$update_data['description'] = $description;
|
||||||
$update_data['id'] = $id;
|
$update_data['id'] = $id;
|
||||||
|
|
||||||
$update_stmt = Database::prepare("
|
$update_stmt = Database::prepare("
|
||||||
@@ -1634,7 +1643,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
|||||||
`tlsv13_cipher_list` = :tlsv13_cipher_list,
|
`tlsv13_cipher_list` = :tlsv13_cipher_list,
|
||||||
`ssl_enabled` = :sslenabled,
|
`ssl_enabled` = :sslenabled,
|
||||||
`ssl_honorcipherorder` = :honorcipherorder,
|
`ssl_honorcipherorder` = :honorcipherorder,
|
||||||
`ssl_sessiontickets` = :sessiontickets
|
`ssl_sessiontickets` = :sessiontickets,
|
||||||
|
`description` = :description
|
||||||
WHERE `id` = :id
|
WHERE `id` = :id
|
||||||
");
|
");
|
||||||
Database::pexecute($update_stmt, $update_data, true, true);
|
Database::pexecute($update_stmt, $update_data, true, true);
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
|||||||
// alternative email address to send info to
|
// alternative email address to send info to
|
||||||
if (Settings::Get('panel.sendalternativemail') == 1) {
|
if (Settings::Get('panel.sendalternativemail') == 1) {
|
||||||
$alternative_email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($alternative_email, 'alternative_email', '', '', array(), true));
|
$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);
|
\Froxlor\UI\Response::standard_error('alternativeemailiswrong', $alternative_email, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -192,7 +192,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
|||||||
$replace_arr = array(
|
$replace_arr = array(
|
||||||
'EMAIL' => $email_full,
|
'EMAIL' => $email_full,
|
||||||
'USERNAME' => $username,
|
'USERNAME' => $username,
|
||||||
'PASSWORD' => $password,
|
'PASSWORD' => htmlentities(htmlentities($password)),
|
||||||
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($customer),
|
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($customer),
|
||||||
'NAME' => $customer['name'],
|
'NAME' => $customer['name'],
|
||||||
'FIRSTNAME' => $customer['firstname'],
|
'FIRSTNAME' => $customer['firstname'],
|
||||||
@@ -236,7 +236,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
|||||||
$this->mailer()->clearAddresses();
|
$this->mailer()->clearAddresses();
|
||||||
|
|
||||||
// customer wants to send the e-mail to an alternative email address too
|
// 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
|
// get template for mail subject
|
||||||
$mail_subject = $this->getMailTemplate($customer, 'mails', 'pop_success_alternative_subject', $replace_arr, $this->lng['mails']['pop_success_alternative']['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
|
// get template for mail body
|
||||||
@@ -302,6 +302,8 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
|||||||
* optional, update quota
|
* optional, update quota
|
||||||
* @param string $email_password
|
* @param string $email_password
|
||||||
* optional, update password
|
* optional, update password
|
||||||
|
* @param bool $deactivated
|
||||||
|
* optional, admin-only
|
||||||
*
|
*
|
||||||
* @access admin, customer
|
* @access admin, customer
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
@@ -331,6 +333,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
|||||||
|
|
||||||
$password = $this->getParam('email_password', true, '');
|
$password = $this->getParam('email_password', true, '');
|
||||||
$quota = $this->getParam('email_quota', true, $result['quota']);
|
$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
|
// get needed customer info to reduce the email-account-counter by one
|
||||||
$customer = $this->getCustomerData();
|
$customer = $this->getCustomerData();
|
||||||
@@ -372,6 +375,18 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
|||||||
$quota = 0;
|
$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
|
// build update query
|
||||||
if (! empty($upd_query)) {
|
if (! empty($upd_query)) {
|
||||||
$upd_stmt = Database::prepare("
|
$upd_stmt = Database::prepare("
|
||||||
|
|||||||
@@ -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)
|
* optional, required when called as admin (if $loginname is not specified)
|
||||||
* @param string $loginname
|
* @param string $loginname
|
||||||
* optional, required when called as admin (if $customerid is not specified)
|
* 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
|
* @access admin, customer
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
@@ -54,6 +56,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
|||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
$iscatchall = $this->getBoolParam('iscatchall', true, 0);
|
$iscatchall = $this->getBoolParam('iscatchall', true, 0);
|
||||||
|
$description = $this->getParam('description', true, '');
|
||||||
|
|
||||||
// validation
|
// validation
|
||||||
if (substr($domain, 0, 4) != 'xn--') {
|
if (substr($domain, 0, 4) != 'xn--') {
|
||||||
@@ -121,14 +124,16 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
|||||||
`email` = :email,
|
`email` = :email,
|
||||||
`email_full` = :email_full,
|
`email_full` = :email_full,
|
||||||
`iscatchall` = :iscatchall,
|
`iscatchall` = :iscatchall,
|
||||||
`domainid` = :domainid
|
`domainid` = :domainid,
|
||||||
|
`description` = :description
|
||||||
");
|
");
|
||||||
$params = array(
|
$params = array(
|
||||||
"cid" => $customer['customerid'],
|
"cid" => $customer['customerid'],
|
||||||
"email" => $email,
|
"email" => $email,
|
||||||
"email_full" => $email_full,
|
"email_full" => $email_full,
|
||||||
"iscatchall" => $iscatchall,
|
"iscatchall" => $iscatchall,
|
||||||
"domainid" => $domain_check['id']
|
"domainid" => $domain_check['id'],
|
||||||
|
"description" => $description
|
||||||
);
|
);
|
||||||
Database::pexecute($stmt, $params, true, true);
|
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');
|
$customer_ids = $this->getAllowedCustomerIds('email');
|
||||||
$params['idea'] = ($id <= 0 ? $emailaddr : $id);
|
$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
|
FROM `" . TABLE_MAIL_VIRTUAL . "` v
|
||||||
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON v.`popaccountid` = u.`id`
|
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON v.`popaccountid` = u.`id`
|
||||||
WHERE v.`customerid` IN (" . implode(", ", $customer_ids) . ")
|
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)
|
* optional, required when called as admin (if $customerid is not specified)
|
||||||
* @param boolean $iscatchall
|
* @param boolean $iscatchall
|
||||||
* optional
|
* optional
|
||||||
|
* @param string $description
|
||||||
|
* optional custom description (currently not used/shown in the frontend), default empty
|
||||||
*
|
*
|
||||||
* @access admin, customer
|
* @access admin, customer
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
@@ -227,6 +234,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
|||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
$iscatchall = $this->getBoolParam('iscatchall', true, $result['iscatchall']);
|
$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
|
// get needed customer info to reduce the email-address-counter by one
|
||||||
$customer = $this->getCustomerData();
|
$customer = $this->getCustomerData();
|
||||||
@@ -256,12 +264,13 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
|||||||
|
|
||||||
$stmt = Database::prepare("
|
$stmt = Database::prepare("
|
||||||
UPDATE `" . TABLE_MAIL_VIRTUAL . "`
|
UPDATE `" . TABLE_MAIL_VIRTUAL . "`
|
||||||
SET `email` = :email , `iscatchall` = :caflag
|
SET `email` = :email , `iscatchall` = :caflag, `description` = :description
|
||||||
WHERE `customerid`= :cid AND `id`= :id
|
WHERE `customerid`= :cid AND `id`= :id
|
||||||
");
|
");
|
||||||
$params = array(
|
$params = array(
|
||||||
"email" => $email,
|
"email" => $email,
|
||||||
"caflag" => $iscatchall,
|
"caflag" => $iscatchall,
|
||||||
|
"description" => $description,
|
||||||
"cid" => $customer['customerid'],
|
"cid" => $customer['customerid'],
|
||||||
"id" => $id
|
"id" => $id
|
||||||
);
|
);
|
||||||
@@ -300,7 +309,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
|||||||
$result = array();
|
$result = array();
|
||||||
$query_fields = array();
|
$query_fields = array();
|
||||||
$result_stmt = Database::prepare("
|
$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
|
FROM `" . TABLE_MAIL_VIRTUAL . "` m
|
||||||
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON (m.`domainid` = d.`id`)
|
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON (m.`domainid` = d.`id`)
|
||||||
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON (m.`popaccountid` = u.`id`)
|
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON (m.`popaccountid` = u.`id`)
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
|||||||
'COMPANY' => $customer['company'],
|
'COMPANY' => $customer['company'],
|
||||||
'CUSTOMER_NO' => $customer['customernumber'],
|
'CUSTOMER_NO' => $customer['customernumber'],
|
||||||
'USR_NAME' => $username,
|
'USR_NAME' => $username,
|
||||||
'USR_PASS' => $password,
|
'USR_PASS' => htmlentities(htmlentities($password)),
|
||||||
'USR_PATH' => \Froxlor\FileDir::makeCorrectDir(str_replace($customer['documentroot'], "/", $path))
|
'USR_PATH' => \Froxlor\FileDir::makeCorrectDir(str_replace($customer['documentroot'], "/", $path))
|
||||||
);
|
);
|
||||||
// get template for mail subject
|
// get template for mail subject
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
|||||||
'COMPANY' => $userinfo['company'],
|
'COMPANY' => $userinfo['company'],
|
||||||
'CUSTOMER_NO' => $userinfo['customernumber'],
|
'CUSTOMER_NO' => $userinfo['customernumber'],
|
||||||
'DB_NAME' => $username,
|
'DB_NAME' => $username,
|
||||||
'DB_PASS' => $password,
|
'DB_PASS' => htmlentities(htmlentities($password)),
|
||||||
'DB_DESC' => $databasedescription,
|
'DB_DESC' => $databasedescription,
|
||||||
'DB_SRV' => $sql_root['host'],
|
'DB_SRV' => $sql_root['host'],
|
||||||
'PMA_URI' => $pma
|
'PMA_URI' => $pma
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
|||||||
);
|
);
|
||||||
|
|
||||||
$query = "SELECT * FROM `" . TABLE_PANEL_DOMAINS . "`
|
$query = "SELECT * FROM `" . TABLE_PANEL_DOMAINS . "`
|
||||||
WHERE `phpsettingid` = :id";
|
WHERE `phpsettingid` = :id AND `email_only` = '0' AND `phpenabled` = '1'";
|
||||||
|
|
||||||
if (! $with_subdomains) {
|
if (! $with_subdomains) {
|
||||||
$query .= " AND `parentdomainid` = '0'";
|
$query .= " AND `parentdomainid` = '0'";
|
||||||
|
|||||||
@@ -497,8 +497,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
|||||||
|
|
||||||
private static function checkFsFilesAreNewer($domain, $cert_date = 0)
|
private static function checkFsFilesAreNewer($domain, $cert_date = 0)
|
||||||
{
|
{
|
||||||
$certificate_folder = self::getWorkingDirFromEnv($domain);
|
$certificate_folder = self::getWorkingDirFromEnv(strtolower($domain));
|
||||||
$ssl_file = \Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $domain . '.cer');
|
$ssl_file = \Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . strtolower($domain) . '.cer');
|
||||||
|
|
||||||
if (is_dir($certificate_folder) && file_exists($ssl_file) && is_readable($ssl_file)) {
|
if (is_dir($certificate_folder) && file_exists($ssl_file) && is_readable($ssl_file)) {
|
||||||
$cert_data = openssl_x509_parse(file_get_contents($ssl_file));
|
$cert_data = openssl_x509_parse(file_get_contents($ssl_file));
|
||||||
|
|||||||
@@ -181,8 +181,8 @@ class Dns
|
|||||||
// unset special spf required-entry
|
// unset special spf required-entry
|
||||||
unset($required_entries[$entry['type']][md5("@SPF@")]);
|
unset($required_entries[$entry['type']][md5("@SPF@")]);
|
||||||
}
|
}
|
||||||
if (empty($primary_ns) && $entry['type'] == 'NS') {
|
if (empty($primary_ns) && $entry['record'] == '@' && $entry['type'] == 'NS') {
|
||||||
// use the first NS entry as primary ns
|
// use the first NS entry pertaining to the current domain as primary ns
|
||||||
$primary_ns = $entry['content'];
|
$primary_ns = $entry['content'];
|
||||||
}
|
}
|
||||||
// check for CNAME on @, www- or wildcard-Alias and remove A/AAAA record accordingly
|
// check for CNAME on @, www- or wildcard-Alias and remove A/AAAA record accordingly
|
||||||
@@ -365,7 +365,11 @@ class Dns
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PowerDNS does not like multi-line-format
|
// 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'] . " ";
|
$soa_content .= $domain['bindserial'] . " ";
|
||||||
// TODO for now, dummy time-periods
|
// TODO for now, dummy time-periods
|
||||||
$soa_content .= "3600 900 604800 " . (int) Settings::Get('system.defaultttl');
|
$soa_content .= "3600 900 604800 " . (int) Settings::Get('system.defaultttl');
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ final class Froxlor
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Main version variable
|
// Main version variable
|
||||||
const VERSION = '0.10.24';
|
const VERSION = '0.10.25';
|
||||||
|
|
||||||
// Database version (YYYYMMDDC where C is a daily counter)
|
// Database version (YYYYMMDDC where C is a daily counter)
|
||||||
const DBVERSION = '202101200';
|
const DBVERSION = '202103030';
|
||||||
|
|
||||||
// Distribution branding-tag (used for Debian etc.)
|
// Distribution branding-tag (used for Debian etc.)
|
||||||
const BRANDING = '';
|
const BRANDING = '';
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ class Crypt
|
|||||||
$password = \Froxlor\Validate\Validate::validate($password, '/.*[0-9]+.*/', '/.*[0-9]+.*/', 'notrequiredpasswordcomplexity', array(), $json_response);
|
$password = \Froxlor\Validate\Validate::validate($password, '/.*[0-9]+.*/', '/.*[0-9]+.*/', 'notrequiredpasswordcomplexity', array(), $json_response);
|
||||||
}
|
}
|
||||||
if (Settings::Get('panel.password_special_char_required')) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2104,3 +2104,5 @@ $lng['serversettings']['awstats']['logformat']['description'] = 'If you use cust
|
|||||||
$lng['error']['cannotdeletesuperadmin'] = 'The first admin cannot be deleted.';
|
$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['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']['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)';
|
||||||
|
|||||||
@@ -1750,3 +1750,5 @@ $lng['serversettings']['awstats']['logformat']['description'] = 'Wenn ein benutz
|
|||||||
$lng['error']['cannotdeletesuperadmin'] = 'Der erste Administrator kann nicht gelöscht werden.';
|
$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['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']['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)';
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
<if $row['letsencrypt'] == '1'>
|
<if $row['letsencrypt'] == '1'>
|
||||||
<img src="templates/{$theme}/assets/img/icons/ssl_letsencrypt.png" alt="{$lng['panel']['letsencrypt']}" title="{$lng['panel']['letsencrypt']}" />
|
<img src="templates/{$theme}/assets/img/icons/ssl_letsencrypt.png" alt="{$lng['panel']['letsencrypt']}" title="{$lng['panel']['letsencrypt']}" />
|
||||||
</if>
|
</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'])>
|
<if !(isset($row['standardsubdomain']) && $row['standardsubdomain'] == $row['id'])>
|
||||||
<a href="{$linker->getLink(array('section' => 'domains', 'page' => $page, 'action' => 'delete', 'id' => $row['id']))}">
|
<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']}" />
|
<img src="templates/{$theme}/assets/img/icons/delete.png" alt="{$lng['panel']['delete']}" title="{$lng['panel']['delete']}" />
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<if $row['aliasdomain'] == ''>{$row['documentroot']}</if>
|
<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>
|
||||||
<td>
|
<td>
|
||||||
<if $row['caneditdomain'] == '1'>
|
<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']}" />
|
<img src="templates/{$theme}/assets/img/icons/view.png" alt="{$lng['panel']['viewlogs']}" title="{$lng['panel']['viewlogs']}" />
|
||||||
</a>
|
</a>
|
||||||
</if>
|
</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']))}">
|
<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']}" />
|
<img src="templates/{$theme}/assets/img/icons/delete.png" alt="{$lng['panel']['delete']}" title="{$lng['panel']['delete']}" />
|
||||||
</a>
|
</a>
|
||||||
@@ -46,10 +46,10 @@
|
|||||||
<if $row['letsencrypt'] == '1'>
|
<if $row['letsencrypt'] == '1'>
|
||||||
<img src="templates/{$theme}/assets/img/icons/ssl_letsencrypt.png" alt="{$lng['panel']['letsencrypt']}" title="{$lng['panel']['letsencrypt']}" />
|
<img src="templates/{$theme}/assets/img/icons/ssl_letsencrypt.png" alt="{$lng['panel']['letsencrypt']}" title="{$lng['panel']['letsencrypt']}" />
|
||||||
</if>
|
</if>
|
||||||
<if $row['parentdomainid'] == '0' && !(isset($row['domainaliasid']) && $row['domainaliasid'] != 0)>
|
<if $row['parentdomainid'] == '0' && (!isset($row['domainaliasid']) || empty($row['domainaliasid']))>
|
||||||
({$lng['domains']['isassigneddomain']})
|
({$lng['domains']['isassigneddomain']})
|
||||||
</if>
|
</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>
|
<a href="{$linker->getLink(array('section' => 'domains', 'page' => 'domains', 'searchfield' => 'd.aliasdomain', 'searchtext' => $row['id']))}">{$lng['domains']['hasaliasdomains']}</a>
|
||||||
</if>
|
</if>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -115,6 +115,14 @@ class CustomersTest extends TestCase
|
|||||||
$json_result = Customers::getLocal($admin_userdata)->listing();
|
$json_result = Customers::getLocal($admin_userdata)->listing();
|
||||||
$result = json_decode($json_result, true)['data'];
|
$result = json_decode($json_result, true)['data'];
|
||||||
$this->assertEquals(1, $result['count']);
|
$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();
|
$json_result = Customers::getLocal($admin_userdata)->listingCount();
|
||||||
$result = json_decode($json_result, true)['data'];
|
$result = json_decode($json_result, true)['data'];
|
||||||
|
|||||||
@@ -32,13 +32,15 @@ class DomainsTest extends TestCase
|
|||||||
'ssl_protocols' => array(
|
'ssl_protocols' => array(
|
||||||
'TLSv1.2',
|
'TLSv1.2',
|
||||||
'TLSv1.3'
|
'TLSv1.3'
|
||||||
)
|
),
|
||||||
|
'description' => 'awesome domain'
|
||||||
];
|
];
|
||||||
$json_result = Domains::getLocal($admin_userdata, $data)->add();
|
$json_result = Domains::getLocal($admin_userdata, $data)->add();
|
||||||
$result = json_decode($json_result, true)['data'];
|
$result = json_decode($json_result, true)['data'];
|
||||||
$this->assertEquals($customer_userdata['documentroot'] . 'test.local/', $result['documentroot']);
|
$this->assertEquals($customer_userdata['documentroot'] . 'test.local/', $result['documentroot']);
|
||||||
$this->assertTrue(in_array('TLSv1.3', explode(",", $result['ssl_protocols'])));
|
$this->assertTrue(in_array('TLSv1.3', explode(",", $result['ssl_protocols'])));
|
||||||
$this->assertEquals('0', $result['isemaildomain']);
|
$this->assertEquals('0', $result['isemaildomain']);
|
||||||
|
$this->assertEquals('awesome domain', $result['description']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -207,7 +209,8 @@ class DomainsTest extends TestCase
|
|||||||
'domainname' => 'test.local',
|
'domainname' => 'test.local',
|
||||||
'email_only' => 1,
|
'email_only' => 1,
|
||||||
'override_tls' => 0,
|
'override_tls' => 0,
|
||||||
'documentroot' => 'web'
|
'documentroot' => 'web',
|
||||||
|
'description' => 'changed desc'
|
||||||
];
|
];
|
||||||
$json_result = Domains::getLocal($admin_userdata, $data)->update();
|
$json_result = Domains::getLocal($admin_userdata, $data)->update();
|
||||||
$result = json_decode($json_result, true)['data'];
|
$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->assertFalse(in_array('TLSv1.3', explode(",", $result['ssl_protocols'])));
|
||||||
$this->assertEquals('test.local', $result['domain']);
|
$this->assertEquals('test.local', $result['domain']);
|
||||||
$this->assertEquals($customer_userdata['documentroot'] . 'web/', $result['documentroot']);
|
$this->assertEquals($customer_userdata['documentroot'] . 'web/', $result['documentroot']);
|
||||||
|
$this->assertEquals('changed desc', $result['description']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -36,12 +36,14 @@ class MailsTest extends TestCase
|
|||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'email_part' => 'info',
|
'email_part' => 'info',
|
||||||
'domain' => 'test2.local'
|
'domain' => 'test2.local',
|
||||||
|
'description' => 'awesome email'
|
||||||
];
|
];
|
||||||
$json_result = Emails::getLocal($customer_userdata, $data)->add();
|
$json_result = Emails::getLocal($customer_userdata, $data)->add();
|
||||||
$result = json_decode($json_result, true)['data'];
|
$result = json_decode($json_result, true)['data'];
|
||||||
$this->assertEquals("info@test2.local", $result['email_full']);
|
$this->assertEquals("info@test2.local", $result['email_full']);
|
||||||
$this->assertEquals(0, $result['iscatchall']);
|
$this->assertEquals(0, $result['iscatchall']);
|
||||||
|
$this->assertEquals('awesome email', $result['description']);
|
||||||
|
|
||||||
// reset setting
|
// reset setting
|
||||||
Settings::Set('panel.customer_hide_options', '', true);
|
Settings::Set('panel.customer_hide_options', '', true);
|
||||||
@@ -87,11 +89,13 @@ class MailsTest extends TestCase
|
|||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'emailaddr' => 'catchall@test2.local',
|
'emailaddr' => 'catchall@test2.local',
|
||||||
'iscatchall' => 1
|
'iscatchall' => 1,
|
||||||
|
'description' => 'now with catchall'
|
||||||
];
|
];
|
||||||
$json_result = Emails::getLocal($customer_userdata, $data)->update();
|
$json_result = Emails::getLocal($customer_userdata, $data)->update();
|
||||||
$result = json_decode($json_result, true)['data'];
|
$result = json_decode($json_result, true)['data'];
|
||||||
$this->assertEquals(1, $result['iscatchall']);
|
$this->assertEquals(1, $result['iscatchall']);
|
||||||
|
$this->assertEquals('now with catchall', $result['description']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCustomerEmailForwardersAdd()
|
public function testCustomerEmailForwardersAdd()
|
||||||
@@ -444,6 +448,36 @@ class MailsTest extends TestCase
|
|||||||
$this->assertEquals(0, $result['quota']);
|
$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()
|
public function testAdminEmailAccountsUndefinedGet()
|
||||||
{
|
{
|
||||||
global $admin_userdata;
|
global $admin_userdata;
|
||||||
|
|||||||
Reference in New Issue
Block a user