store IDN email-usernames in ACE, as dovecot/postfix need them this way

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann
2024-09-26 09:22:11 +02:00
parent 40aa48a6d4
commit 140c6c9549
4 changed files with 14 additions and 8 deletions

View File

@@ -69,7 +69,7 @@ class EmailDomains extends ApiCommand implements ResourceEntity
$result = []; $result = [];
$query_fields = []; $query_fields = [];
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT DISTINCT d.domain, e.domainid, SELECT DISTINCT d.domain, d.domain_ace, e.domainid,
COUNT(e.email) as addresses, COUNT(e.email) as addresses,
IFNULL(SUM(CASE WHEN e.popaccountid > 0 THEN 1 ELSE 0 END), 0) as accounts, IFNULL(SUM(CASE WHEN e.popaccountid > 0 THEN 1 ELSE 0 END), 0) as accounts,
IFNULL(SUM( IFNULL(SUM(

View File

@@ -92,10 +92,11 @@ class Emails extends ApiCommand implements ResourceEntity
$description = $this->getParam('description', true, ''); $description = $this->getParam('description', true, '');
// validation // validation
$idna_convert = new IdnaWrapper();
if (substr($domain, 0, 4) != 'xn--') { if (substr($domain, 0, 4) != 'xn--') {
$idna_convert = new IdnaWrapper();
$domain = $idna_convert->encode(Validate::validate($domain, 'domain', '', '', [], true)); $domain = $idna_convert->encode(Validate::validate($domain, 'domain', '', '', [], true));
} }
$email_part = $idna_convert->encode($email_part);
// check domain and whether it's an email-enabled domain // check domain and whether it's an email-enabled domain
// use internal call because the customer might have 'domains' in customer_hide_options // use internal call because the customer might have 'domains' in customer_hide_options
@@ -103,10 +104,10 @@ class Emails extends ApiCommand implements ResourceEntity
'domainname' => $domain 'domainname' => $domain
], true); ], true);
if ((int)$domain_check['isemaildomain'] == 0) { if ((int)$domain_check['isemaildomain'] == 0) {
Response::standardError('maindomainnonexist', $domain, true); Response::standardError('maindomainnonexist', $idna_convert->decode($domain), true);
} }
if ((int)$domain_check['deactivated'] == 1) { if ((int)$domain_check['deactivated'] == 1) {
Response::standardError('maindomaindeactivated', $domain, true); Response::standardError('maindomaindeactivated', $idna_convert->decode($domain), true);
} }
if (Settings::Get('catchall.catchall_enabled') != '1') { if (Settings::Get('catchall.catchall_enabled') != '1') {
@@ -127,7 +128,7 @@ class Emails extends ApiCommand implements ResourceEntity
// validate it // validate it
if (!Validate::validateEmail($email_full)) { if (!Validate::validateEmail($email_full)) {
Response::standardError('emailiswrong', $email_full, true); Response::standardError('emailiswrong', $idna_convert->decode($email_full), true);
} }
// get needed customer info to reduce the email-address-counter by one // get needed customer info to reduce the email-address-counter by one
@@ -148,7 +149,7 @@ class Emails extends ApiCommand implements ResourceEntity
if ($email_check) { if ($email_check) {
if (strtolower($email_check['email_full']) == strtolower($email_full)) { if (strtolower($email_check['email_full']) == strtolower($email_full)) {
Response::standardError('emailexistalready', $email_full, true); Response::standardError('emailexistalready', $idna_convert->decode($email_full), true);
} elseif ($email_check['email'] == $email) { } elseif ($email_check['email'] == $email) {
Response::standardError('youhavealreadyacatchallforthisdomain', '', true); Response::standardError('youhavealreadyacatchallforthisdomain', '', true);
} }
@@ -226,7 +227,7 @@ class Emails extends ApiCommand implements ResourceEntity
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) . ")
AND " . (is_numeric($params['idea']) ? "v.`id`= :idea" : "(v.`email` = :idea OR v.`email_full` = :idea)" AND " . (is_numeric($params['idea']) ? "v.`id`= :idea" : "(v.`email` = :idea OR v.`email_full` = :idea)"
)); ));
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
$this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_INFO, "[API] get email address '" . $result['email_full'] . "'"); $this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_INFO, "[API] get email address '" . $result['email_full'] . "'");
@@ -396,7 +397,10 @@ class Emails extends ApiCommand implements ResourceEntity
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON (m.`popaccountid` = u.`id`) LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON (m.`popaccountid` = u.`id`)
WHERE m.`customerid` IN (" . implode(", ", $customer_ids) . ")" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit()); WHERE m.`customerid` IN (" . implode(", ", $customer_ids) . ")" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
Database::pexecute($result_stmt, $query_fields, true, true); Database::pexecute($result_stmt, $query_fields, true, true);
$idna_convert = new IdnaWrapper();
while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(PDO::FETCH_ASSOC)) {
$row['email'] = $idna_convert->decode($row['email']);
$row['email_full'] = $idna_convert->decode($row['email_full']);
$result[] = $row; $result[] = $row;
} }
$this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_INFO, "[API] list email-addresses"); $this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_INFO, "[API] list email-addresses");

View File

@@ -321,6 +321,7 @@ EOC;
WHERE WHERE
dom.`customerid` = cust.`customerid` dom.`customerid` = cust.`customerid`
AND cust.deactivated = 0 AND cust.deactivated = 0
AND dom.deactivated = 0
AND dom.`ssl_enabled` = 1 AND dom.`ssl_enabled` = 1
AND dom.`letsencrypt` = 1 AND dom.`letsencrypt` = 1
AND dom.`aliasdomain` IS NULL AND dom.`aliasdomain` IS NULL
@@ -383,6 +384,7 @@ EOC;
WHERE WHERE
dom.`customerid` = cust.`customerid` dom.`customerid` = cust.`customerid`
AND cust.deactivated = 0 AND cust.deactivated = 0
AND dom.deactivated = 0
AND dom.`ssl_enabled` = 1 AND dom.`ssl_enabled` = 1
AND dom.`letsencrypt` = 1 AND dom.`letsencrypt` = 1
AND dom.`aliasdomain` IS NULL AND dom.`aliasdomain` IS NULL

View File

@@ -35,7 +35,7 @@ return [
'self_overview' => ['section' => 'email', 'page' => 'overview'], 'self_overview' => ['section' => 'email', 'page' => 'overview'],
'default_sorting' => ['d.domain' => 'asc'], 'default_sorting' => ['d.domain' => 'asc'],
'columns' => [ 'columns' => [
'd.domain' => [ 'd.domain_ace' => [
'label' => 'Domain', 'label' => 'Domain',
'field' => 'domain', 'field' => 'domain',
], ],