mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2025-12-13 09:56:01 +00:00
[Rspamd][Web] Internal alias support
This commit is contained in:
@@ -56,7 +56,7 @@ function normalize_email($email) {
|
||||
$email = explode('@', $email);
|
||||
$email[0] = str_replace('.', '', $email[0]);
|
||||
$email = implode('@', $email);
|
||||
}
|
||||
}
|
||||
$gm_alt = "@googlemail.com";
|
||||
if (substr_compare($email, $gm_alt, -strlen($gm_alt)) == 0) {
|
||||
$email = explode('@', $email);
|
||||
@@ -114,7 +114,7 @@ function ucl_rcpts($object, $type) {
|
||||
$rcpt[] = str_replace('/', '\/', $row['address']);
|
||||
}
|
||||
// Aliases by alias domains
|
||||
$stmt = $pdo->prepare("SELECT CONCAT(`local_part`, '@', `alias_domain`.`alias_domain`) AS `alias` FROM `mailbox`
|
||||
$stmt = $pdo->prepare("SELECT CONCAT(`local_part`, '@', `alias_domain`.`alias_domain`) AS `alias` FROM `mailbox`
|
||||
LEFT OUTER JOIN `alias_domain` ON `mailbox`.`domain` = `alias_domain`.`target_domain`
|
||||
WHERE `mailbox`.`username` = :object");
|
||||
$stmt->execute(array(
|
||||
@@ -184,7 +184,7 @@ while ($row = array_shift($rows)) {
|
||||
rcpt = <?=json_encode($rcpt, JSON_UNESCAPED_SLASHES);?>;
|
||||
<?php
|
||||
}
|
||||
$stmt = $pdo->prepare("SELECT `option`, `value` FROM `filterconf`
|
||||
$stmt = $pdo->prepare("SELECT `option`, `value` FROM `filterconf`
|
||||
WHERE (`option` = 'highspamlevel' OR `option` = 'lowspamlevel')
|
||||
AND `object`= :object");
|
||||
$stmt->execute(array(':object' => $row['object']));
|
||||
@@ -468,4 +468,36 @@ while ($row = array_shift($rows)) {
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
// Start internal aliases
|
||||
|
||||
$stmt = $pdo->query("SELECT `id`, `address`, `domain` FROM `alias` WHERE `active` = '1' AND `internal` = '1'");
|
||||
$aliases = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
while ($alias = array_shift($aliases)) {
|
||||
// build allowed_domains regex and add target domain and alias domains
|
||||
$stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `active` = '1' AND `target_domain` = :target_domain");
|
||||
$stmt->execute(array(':target_domain' => $alias['domain']));
|
||||
$allowed_domains = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$allowed_domains = array_map(function($item) {
|
||||
return str_replace('.', '\.', $item['alias_domain']);
|
||||
}, $allowed_domains);
|
||||
$allowed_domains[] = str_replace('.', '\.', $alias['domain']);
|
||||
$allowed_domains = implode('|', $allowed_domains);
|
||||
?>
|
||||
internal_alias_<?=$alias['id'];?> {
|
||||
priority = 10;
|
||||
rcpt = "<?=$alias['address'];?>";
|
||||
from = "/^((?!.*@(<?=$allowed_domains;?>)).)*$/";
|
||||
apply "default" {
|
||||
MAILCOW_INTERNAL_ALIAS = 9999.0;
|
||||
}
|
||||
symbols [
|
||||
"MAILCOW_INTERNAL_ALIAS"
|
||||
]
|
||||
}
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
}
|
||||
|
||||
@@ -684,15 +684,16 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
return true;
|
||||
break;
|
||||
case 'alias':
|
||||
$addresses = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['address']));
|
||||
$gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['goto']));
|
||||
$active = intval($_data['active']);
|
||||
$sogo_visible = intval($_data['sogo_visible']);
|
||||
$goto_null = intval($_data['goto_null']);
|
||||
$goto_spam = intval($_data['goto_spam']);
|
||||
$goto_ham = intval($_data['goto_ham']);
|
||||
$addresses = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['address']));
|
||||
$gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['goto']));
|
||||
$internal = intval($_data['internal']);
|
||||
$active = intval($_data['active']);
|
||||
$sogo_visible = intval($_data['sogo_visible']);
|
||||
$goto_null = intval($_data['goto_null']);
|
||||
$goto_spam = intval($_data['goto_spam']);
|
||||
$goto_ham = intval($_data['goto_ham']);
|
||||
$private_comment = $_data['private_comment'];
|
||||
$public_comment = $_data['public_comment'];
|
||||
$public_comment = $_data['public_comment'];
|
||||
if (strlen($private_comment) > 160 | strlen($public_comment) > 160){
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
@@ -842,8 +843,8 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
);
|
||||
continue;
|
||||
}
|
||||
$stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `public_comment`, `private_comment`, `goto`, `domain`, `sogo_visible`, `active`)
|
||||
VALUES (:address, :public_comment, :private_comment, :goto, :domain, :sogo_visible, :active)");
|
||||
$stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `public_comment`, `private_comment`, `goto`, `domain`, `sogo_visible`, `internal`, `active`)
|
||||
VALUES (:address, :public_comment, :private_comment, :goto, :domain, :sogo_visible, :internal, :active)");
|
||||
if (!filter_var($address, FILTER_VALIDATE_EMAIL) === true) {
|
||||
$stmt->execute(array(
|
||||
':address' => '@'.$domain,
|
||||
@@ -853,6 +854,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
':goto' => $goto,
|
||||
':domain' => $domain,
|
||||
':sogo_visible' => $sogo_visible,
|
||||
':internal' => $internal,
|
||||
':active' => $active
|
||||
));
|
||||
}
|
||||
@@ -864,6 +866,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
':goto' => $goto,
|
||||
':domain' => $domain,
|
||||
':sogo_visible' => $sogo_visible,
|
||||
':internal' => $internal,
|
||||
':active' => $active
|
||||
));
|
||||
}
|
||||
@@ -2481,6 +2484,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
foreach ($ids as $id) {
|
||||
$is_now = mailbox('get', 'alias_details', $id);
|
||||
if (!empty($is_now)) {
|
||||
$internal = (isset($_data['internal'])) ? intval($_data['internal']) : $is_now['internal'];
|
||||
$active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active'];
|
||||
$sogo_visible = (isset($_data['sogo_visible'])) ? intval($_data['sogo_visible']) : $is_now['sogo_visible'];
|
||||
$goto_null = (isset($_data['goto_null'])) ? intval($_data['goto_null']) : 0;
|
||||
@@ -2666,6 +2670,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
`domain` = :domain,
|
||||
`goto` = :goto,
|
||||
`sogo_visible`= :sogo_visible,
|
||||
`internal`= :internal,
|
||||
`active`= :active
|
||||
WHERE `id` = :id");
|
||||
$stmt->execute(array(
|
||||
@@ -2675,6 +2680,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
':domain' => $domain,
|
||||
':goto' => $goto,
|
||||
':sogo_visible' => $sogo_visible,
|
||||
':internal' => $internal,
|
||||
':active' => $active,
|
||||
':id' => $is_now['id']
|
||||
));
|
||||
@@ -4700,6 +4706,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
`address`,
|
||||
`public_comment`,
|
||||
`private_comment`,
|
||||
`internal`,
|
||||
`active`,
|
||||
`sogo_visible`,
|
||||
`created`,
|
||||
@@ -4730,6 +4737,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$aliasdata['goto'] = $row['goto'];
|
||||
$aliasdata['address'] = $row['address'];
|
||||
(!filter_var($aliasdata['address'], FILTER_VALIDATE_EMAIL)) ? $aliasdata['is_catch_all'] = 1 : $aliasdata['is_catch_all'] = 0;
|
||||
$aliasdata['internal'] = $row['internal'];
|
||||
$aliasdata['active'] = $row['active'];
|
||||
$aliasdata['active_int'] = $row['active'];
|
||||
$aliasdata['sogo_visible'] = $row['sogo_visible'];
|
||||
|
||||
@@ -184,6 +184,7 @@ function init_db_schema()
|
||||
"private_comment" => "TEXT",
|
||||
"public_comment" => "TEXT",
|
||||
"sogo_visible" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"internal" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||
"active" => "TINYINT(1) NOT NULL DEFAULT '1'"
|
||||
),
|
||||
"keys" => array(
|
||||
|
||||
@@ -1972,6 +1972,15 @@ jQuery(function($){
|
||||
data: 'private_comment',
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: lang.internal,
|
||||
data: 'internal',
|
||||
defaultContent: '',
|
||||
responsivePriority: 6,
|
||||
render: function (data, type) {
|
||||
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.active,
|
||||
data: 'active',
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
"goto_spam": "Nachrichten als <span class=\"text-danger\"><b>Spam</b></span> lernen",
|
||||
"hostname": "Host",
|
||||
"inactive": "Inaktiv",
|
||||
"internal": "Intern",
|
||||
"internal_info": "Interne Aliasse sind nur von der eigenen Domäne oder Alias-Domänen erreichbar.",
|
||||
"kind": "Art",
|
||||
"mailbox_quota_def": "Standard-Quota einer Mailbox",
|
||||
"mailbox_quota_m": "Max. Speicherplatz pro Mailbox (MiB)",
|
||||
@@ -690,6 +692,8 @@
|
||||
"grant_types": "Grant-types",
|
||||
"hostname": "Servername",
|
||||
"inactive": "Inaktiv",
|
||||
"internal": "Intern",
|
||||
"internal_info": "Interne Aliasse sind nur von der eigenen Domäne oder Alias-Domänen erreichbar.",
|
||||
"kind": "Art",
|
||||
"last_modified": "Zuletzt geändert",
|
||||
"lookup_mx": "Ziel mit MX vergleichen (Regex, etwa <code>.*\\.google\\.com</code>, um alle Ziele mit MX *google.com zu routen)",
|
||||
@@ -923,6 +927,7 @@
|
||||
"in_use": "Prozentualer Gebrauch",
|
||||
"inactive": "Inaktiv",
|
||||
"insert_preset": "Beispiel \"%s\" laden",
|
||||
"internal": "Intern",
|
||||
"kind": "Art",
|
||||
"last_mail_login": "Letzter Mail-Login",
|
||||
"last_modified": "Zuletzt geändert",
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
"goto_spam": "Learn as <span class=\"text-danger\"><b>spam</b></span>",
|
||||
"hostname": "Host",
|
||||
"inactive": "Inactive",
|
||||
"internal": "Internal",
|
||||
"internal_info": "Internal aliases are only accessible from the own domain or alias domains.",
|
||||
"kind": "Kind",
|
||||
"mailbox_quota_def": "Default mailbox quota",
|
||||
"mailbox_quota_m": "Max. quota per mailbox (MiB)",
|
||||
@@ -690,6 +692,8 @@
|
||||
"grant_types": "Grant types",
|
||||
"hostname": "Hostname",
|
||||
"inactive": "Inactive",
|
||||
"internal": "Internal",
|
||||
"internal_info": "Internal aliases are only accessible from the own domain or alias domains.",
|
||||
"kind": "Kind",
|
||||
"last_modified": "Last modified",
|
||||
"lookup_mx": "Destination is a regular expression to match against MX name (<code>.*\\.google\\.com</code> to route all mail targeted to a MX ending in google.com over this hop)",
|
||||
@@ -928,6 +932,7 @@
|
||||
"in_use": "In use (%)",
|
||||
"inactive": "Inactive",
|
||||
"insert_preset": "Insert example preset \"%s\"",
|
||||
"internal": "Internal",
|
||||
"kind": "Kind",
|
||||
"last_mail_login": "Last mail login",
|
||||
"last_modified": "Last modified",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<br>
|
||||
<form class="form-horizontal" data-id="editalias" role="form" method="post">
|
||||
<input type="hidden" value="0" name="active">
|
||||
<input type="hidden" value="0" name="internal">
|
||||
{% if not skip_sogo %}
|
||||
<input type="hidden" value="0" name="sogo_visible">
|
||||
{% endif %}
|
||||
@@ -33,8 +34,12 @@
|
||||
<div class="form-check">
|
||||
<label><input type="checkbox" class="form-check-input" value="1" name="sogo_visible"{% if result.sogo_visible == '1' %} checked{% endif %}> {{ lang.edit.sogo_visible }}</label>
|
||||
</div>
|
||||
<p class="text-muted">{{ lang.edit.sogo_visible_info }}</p>
|
||||
<small class="text-muted d-block mb-2">{{ lang.edit.sogo_visible_info }}</small>
|
||||
{% endif %}
|
||||
<div class="form-check">
|
||||
<label><input type="checkbox" class="form-check-input" value="1" name="internal"{% if result.internal == '1' %} checked{% endif %}> {{ lang.edit.internal }}</label>
|
||||
</div>
|
||||
<small class="text-muted d-block">{{ lang.edit.internal_info }}</small>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
@@ -777,6 +777,7 @@
|
||||
<div class="modal-body">
|
||||
<form class="form-horizontal" data-cached-form="true" role="form" data-id="add_alias">
|
||||
<input type="hidden" value="0" name="active">
|
||||
<input type="hidden" value="0" name="internal">
|
||||
<div class="row mb-2">
|
||||
<label class="control-label col-sm-2 text-sm-end" for="address">{{ lang.add.alias_address }}</label>
|
||||
<div class="col-sm-10">
|
||||
@@ -803,11 +804,15 @@
|
||||
<div class="form-check">
|
||||
<label><input type="checkbox" class="form-check-input" value="1" name="sogo_visible" checked> {{ lang.edit.sogo_visible }}</label>
|
||||
</div>
|
||||
<p class="text-muted">{{ lang.edit.sogo_visible_info }}</p>
|
||||
<small class="text-muted d-block mb-2">{{ lang.edit.sogo_visible_info }}</small>
|
||||
{% endif %}
|
||||
<div class="form-check">
|
||||
<label><input type="checkbox" class="form-check-input" value="1" name="internal"> {{ lang.add.internal }}</label>
|
||||
</div>
|
||||
<small class="text-muted d-block">{{ lang.edit.internal_info }}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="row mb-4">
|
||||
<div class="offset-sm-2 col-sm-10">
|
||||
<div class="form-check">
|
||||
<label><input type="checkbox" class="form-check-input" value="1" name="active" checked> {{ lang.add.active }}</label>
|
||||
|
||||
Reference in New Issue
Block a user