[Web] Allow to set global sieve filters
This commit is contained in:
parent
32ef5508a0
commit
e1897b0631
@ -62,6 +62,85 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
'msg' => array('mailbox_modified', htmlspecialchars($_SESSION['mailcow_cc_username']))
|
||||
);
|
||||
break;
|
||||
case 'global_filter':
|
||||
if ($_SESSION['mailcow_cc_role'] != "admin") {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$sieve = new Sieve\SieveParser();
|
||||
$script_data = $_data['script_data'];
|
||||
$script_data = str_replace("\r\n", "\n", $script_data); // windows -> unix
|
||||
$script_data = str_replace("\r", "\n", $script_data); // remaining -> unix
|
||||
$filter_type = $_data['filter_type'];
|
||||
try {
|
||||
$sieve->parse($script_data);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => array('sieve_error', $e->getMessage())
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if ($filter_type == 'prefilter') {
|
||||
try {
|
||||
if (file_exists('/global_sieve/before')) {
|
||||
$filter_handle = fopen('/global_sieve/before', 'w');
|
||||
if (!$filter_handle) {
|
||||
throw new Exception($lang['danger']['file_open_error']);
|
||||
}
|
||||
fwrite($filter_handle, $script_data);
|
||||
fclose($filter_handle);
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data_log),
|
||||
'msg' => array('global_filter_write_error', htmlspecialchars($e->getMessage()))
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
elseif ($filter_type == 'postfilter') {
|
||||
try {
|
||||
if (file_exists('/global_sieve/after')) {
|
||||
$filter_handle = fopen('/global_sieve/after', 'w');
|
||||
if (!$filter_handle) {
|
||||
throw new Exception($lang['danger']['file_open_error']);
|
||||
}
|
||||
fwrite($filter_handle, $script_data);
|
||||
fclose($filter_handle);
|
||||
}
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data_log),
|
||||
'msg' => array('global_filter_write_error', htmlspecialchars($e->getMessage()))
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => 'invalid_filter_type'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => 'global_filter_written'
|
||||
);
|
||||
return true;
|
||||
case 'filter':
|
||||
$sieve = new Sieve\SieveParser();
|
||||
if (!isset($_SESSION['acl']['filters']) || $_SESSION['acl']['filters'] != "1" ) {
|
||||
@ -2653,6 +2732,15 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
}
|
||||
return $filters;
|
||||
break;
|
||||
case 'global_filter_details':
|
||||
$global_filters = array();
|
||||
if ($_SESSION['mailcow_cc_role'] != "admin") {
|
||||
return false;
|
||||
}
|
||||
$global_filters['prefilter'] = file_get_contents('/global_sieve/before');
|
||||
$global_filters['postfilter'] = file_get_contents('/global_sieve/after');
|
||||
return $global_filters;
|
||||
break;
|
||||
case 'filter_details':
|
||||
$filter_details = array();
|
||||
if (!is_numeric($_data)) {
|
||||
|
@ -233,7 +233,7 @@ function rspamd($_action, $_data = null) {
|
||||
$map_content = trim($_data['rspamd_map_data']);
|
||||
$map_handle = fopen('/rspamd_custom_maps/' . $map, 'w');
|
||||
if (!$map_handle) {
|
||||
throw new Exception('File cannot be opened for writing.');
|
||||
throw new Exception($lang['danger']['file_open_error']);
|
||||
}
|
||||
fwrite($map_handle, $map_content . PHP_EOL);
|
||||
fclose($map_handle);
|
||||
|
@ -146,12 +146,15 @@ $(document).ready(function() {
|
||||
});
|
||||
// Disable submit button on script change
|
||||
$('.textarea-code').on('keyup', function() {
|
||||
$('#add_filter_btns > #add_sieve_script').attr({"disabled": true});
|
||||
// Disable all "save" buttons, could be a "related button only" function, todo
|
||||
$('.add_sieve_script').attr({"disabled": true});
|
||||
});
|
||||
// Validate script data
|
||||
$("#validate_sieve").click(function( event ) {
|
||||
$(".validate_sieve").click(function( event ) {
|
||||
event.preventDefault();
|
||||
var script = $('#script_data').val();
|
||||
var validation_button = $(this);
|
||||
// Get script_data textarea content from form the button was clicked in
|
||||
var script = $('textarea[name="script_data"]', $(this).parents('form:first')).val();
|
||||
$.ajax({
|
||||
dataType: 'json',
|
||||
url: "/inc/ajax/sieve_validation.php",
|
||||
@ -161,7 +164,7 @@ $(document).ready(function() {
|
||||
var response = (data.responseText);
|
||||
response_obj = JSON.parse(response);
|
||||
if (response_obj.type == "success") {
|
||||
$('#add_filter_btns > #add_sieve_script').attr({"disabled": false});
|
||||
$(validation_button).next().attr({"disabled": false});
|
||||
}
|
||||
mailcow_alert_box(response_obj.msg, response_obj.type);
|
||||
},
|
||||
|
@ -167,6 +167,9 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
|
||||
case "filter":
|
||||
process_add_return(mailbox('add', 'filter', $attr));
|
||||
break;
|
||||
case "global-filter":
|
||||
process_add_return(mailbox('add', 'global_filter', $attr));
|
||||
break;
|
||||
case "domain-policy":
|
||||
process_add_return(policy('add', 'domain', $attr));
|
||||
break;
|
||||
@ -332,6 +335,36 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
|
||||
}
|
||||
break;
|
||||
|
||||
case "global_filters":
|
||||
$global_filters = mailbox('get', 'global_filter_details');
|
||||
switch ($object) {
|
||||
case "all":
|
||||
if (!empty($global_filters)) {
|
||||
process_get_return($global_filters);
|
||||
}
|
||||
else {
|
||||
echo '{}';
|
||||
}
|
||||
break;
|
||||
case "prefilter":
|
||||
if (!empty($global_filters['prefilter'])) {
|
||||
process_get_return($global_filters['prefilter']);
|
||||
}
|
||||
else {
|
||||
echo '{}';
|
||||
}
|
||||
break;
|
||||
case "postfilter":
|
||||
if (!empty($global_filters['postfilter'])) {
|
||||
process_get_return($global_filters['postfilter']);
|
||||
}
|
||||
else {
|
||||
echo '{}';
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case "rl-domain":
|
||||
switch ($object) {
|
||||
case "all":
|
||||
|
@ -594,7 +594,7 @@
|
||||
"last_run": "Naposledy spuštěno",
|
||||
"excludes": "Vyloučené",
|
||||
"last_run_reset": "Plánovat další",
|
||||
"sieve_info": "Můžete uložit více filtrů pro každého uživatele, ale současně může být aktivní pouze jeden prefilter a jeden postfilter.<br>\r\nKaždý filtr bude proveden v daném pořadí. Ani chyba při vykonávání skriptu nebo snaha o pozdržení nezastaví vykonání dalších skriptů.<br>\r\n<a href=\"https://github.com/mailcow/mailcow-dockerized/blob/master/data/conf/dovecot/global_sieve_before\" target=\"_blank\">Global sieve prefilter</a> → Prefilter → Uživatelské skripty → Postfilter → <a href=\"https://github.com/mailcow/mailcow-dockerized/blob/master/data/conf/dovecot/global_sieve_after\" target=\"_blank\">Global sieve postfilter</a>",
|
||||
"sieve_info": "Můžete uložit více filtrů pro každého uživatele, ale současně může být aktivní pouze jeden prefilter a jeden postfilter.<br>\r\nKaždý filtr bude proveden v daném pořadí. Ani chyba při vykonávání skriptu nebo snaha o pozdržení nezastaví vykonání dalších skriptů.<br><br>Global sieve prefilter → Prefilter → Uživatelské skripty → Postfilter → Global sieve postfilter",
|
||||
"sogo_visible": "Alias dostupný v SOGo",
|
||||
"sogo_visible_y": "Zobrazit alias v SOGo",
|
||||
"sogo_visible_n": "Skrýt alias v SOGo",
|
||||
|
@ -24,6 +24,8 @@
|
||||
"apps": "Apps"
|
||||
},
|
||||
"danger": {
|
||||
"invalid_filter_type": "Ungültiger Filtertyp",
|
||||
"file_open_error": "Datei kann nicht zum Schreiben geöffnet werden",
|
||||
"transport_dest_exists": "Transport Maps Ziel \"%s\" existiert bereits",
|
||||
"unlimited_quota_acl": "Unendliche Quota untersagt durch ACL",
|
||||
"mysql_error": "MySQL Fehler: %s",
|
||||
@ -60,6 +62,7 @@
|
||||
"settings_map_invalid": "Regel ID %s ist ungültig",
|
||||
"app_passwd_id_invalid": "App Passwort ID %s ist ungültig",
|
||||
"global_map_invalid": "Rspamd Map %s ist ungültig",
|
||||
"global_filter_write_error": "Kann Filterdatei nicht schreiben: %s",
|
||||
"global_map_write_error": "Kann globale Map ID %s nicht schreiben: %s",
|
||||
"invalid_host": "Ungültiger Host: %s",
|
||||
"relayhost_invalid": "Mapeintrag %s ist ungültig",
|
||||
@ -132,6 +135,7 @@
|
||||
"extra_acl_invalid_domain": "Externe Absenderadresse \"%s\" verwendet eine ungültige Domain"
|
||||
},
|
||||
"success": {
|
||||
"global_filter_written": "Filterdatei wurde erfolreich geschrieben",
|
||||
"learned_ham": "ID %s wurde erfolreich als Ham gelernt",
|
||||
"verified_totp_login": "TOTP Anmeldung verifiziert",
|
||||
"verified_u2f_login": "U2F Anmeldung verifiziert",
|
||||
@ -632,7 +636,7 @@
|
||||
"last_run": "Letzte Ausführung",
|
||||
"last_run_reset": "Als nächstes ausführen",
|
||||
"excludes": "Ausschlüsse",
|
||||
"sieve_info": "Es können mehrere Filter pro Benutzer existieren, aber nur ein Filter eines Typs (Pre-/Postfilter) kann gleichzeitig aktiv sein.<br>\r\nDie Ausführung erfolgt in nachstehender Reihenfolge. Ein fehlgeschlagenes Script sowie der Befehl \"keep;\" stoppen die weitere Verarbeitung <b>nicht</b>.<br>\r\n<a href=\"https://github.com/mailcow/mailcow-dockerized/blob/master/data/conf/dovecot/global_sieve_before\" target=\"_blank\">Global sieve prefilter</a> → Prefilter → User scripts → Postfilter → <a href=\"https://github.com/mailcow/mailcow-dockerized/blob/master/data/conf/dovecot/global_sieve_after\" target=\"_blank\">Global sieve postfilter</a>",
|
||||
"sieve_info": "Es können mehrere Filter pro Benutzer existieren, aber nur ein Filter eines Typs (Pre-/Postfilter) kann gleichzeitig aktiv sein.<br>\r\nDie Ausführung erfolgt in nachstehender Reihenfolge. Ein fehlgeschlagenes Script sowie der Befehl \"keep;\" stoppen die weitere Verarbeitung <b>nicht</b>.<br><br>Global sieve prefilter → Prefilter → User scripts → Postfilter → Global sieve postfilter",
|
||||
"sogo_visible": "Alias Sichtbarkeit in SOGo",
|
||||
"sogo_visible_y": "Alias in SOGo anzeigen",
|
||||
"sogo_visible_n": "Alias in SOGo verbergen",
|
||||
|
@ -24,6 +24,8 @@
|
||||
"hibp_ok": "No match found."
|
||||
},
|
||||
"danger": {
|
||||
"invalid_filter_type": "Invalid filter type",
|
||||
"file_open_error": "File cannot be opened for writing",
|
||||
"transport_dest_exists": "Transport destination \"%s\" exists",
|
||||
"unlimited_quota_acl": "Unlimited quota prohibited by ACL",
|
||||
"mysql_error": "MySQL error: %s",
|
||||
@ -61,6 +63,7 @@
|
||||
"app_passwd_id_invalid": "App password ID %s invalid",
|
||||
"global_map_invalid": "Global map ID %s invalid",
|
||||
"global_map_write_error": "Could not write global map ID %s: %s",
|
||||
"global_filter_write_error": "Could not write filter file: %s",
|
||||
"invalid_host": "Invalid host specified: %s",
|
||||
"relayhost_invalid": "Map entry %s is invalid",
|
||||
"dkim_domain_or_sel_invalid": "DKIM domain or selector invalid: %s",
|
||||
@ -132,6 +135,7 @@
|
||||
"extra_acl_invalid_domain": "External sender \"%s\" uses an invalid domain"
|
||||
},
|
||||
"success": {
|
||||
"global_filter_written": "Filter was successfully written to file",
|
||||
"learned_ham": "Successfully learned ID % as ham",
|
||||
"verified_totp_login": "Verified TOTP login",
|
||||
"verified_u2f_login": "Verified U2F login",
|
||||
@ -634,7 +638,7 @@
|
||||
"last_run": "Last run",
|
||||
"excludes": "Excludes",
|
||||
"last_run_reset": "Schedule next",
|
||||
"sieve_info": "You can store multiple filters per user, but only one prefilter and one postfilter can be active at the same time.<br>\r\nEach filter will be processed in the described order. Neither a failed script nor an issued \"keep;\" will stop processing of further scripts.<br>\r\n<a href=\"https://github.com/mailcow/mailcow-dockerized/blob/master/data/conf/dovecot/global_sieve_before\" target=\"_blank\">Global sieve prefilter</a> → Prefilter → User scripts → Postfilter → <a href=\"https://github.com/mailcow/mailcow-dockerized/blob/master/data/conf/dovecot/global_sieve_after\" target=\"_blank\">Global sieve postfilter</a>",
|
||||
"sieve_info": "You can store multiple filters per user, but only one prefilter and one postfilter can be active at the same time.<br>\r\nEach filter will be processed in the described order. Neither a failed script nor an issued \"keep;\" will stop processing of further scripts.<br><br>Global sieve prefilter → Prefilter → User scripts → Postfilter → Global sieve postfilter",
|
||||
"sogo_visible": "Alias is visible in SOGo",
|
||||
"sogo_visible_y": "Show alias in SOGo",
|
||||
"sogo_visible_n": "Hide alias in SOGo",
|
||||
|
@ -633,7 +633,7 @@
|
||||
"running": "В процессе выполнения",
|
||||
"set_postfilter": "Использовать как постфильтр",
|
||||
"set_prefilter": "Использовать как предв. фильтр",
|
||||
"sieve_info": "Вы можете сохранить несколько фильтров для каждого пользователя, но только один предварительный фильтр и один постфильтр могут быть активными одновременно.<br>\r\n Каждый фильтр будет обработан в описанном порядке. Не сломаный скрипт, не <code>keep;</code> не остановит обработку дальнейших скриптов.<br>\r\n <a href=\"https://github.com/mailcow/mailcow-dockerized/blob/master/data/conf/dovecot/global_sieve_before\" target=\"_blank\">Global sieve prefilter</a> → Prefilter → User scripts → Postfilter → <a href=\"https://github.com/mailcow/mailcow-dockerized/blob/master/data/conf/dovecot/global_sieve_after\" target=\"_blank\">Global sieve postfilter</a>",
|
||||
"sieve_info": "Вы можете сохранить несколько фильтров для каждого пользователя, но только один предварительный фильтр и один постфильтр могут быть активными одновременно.<br>\r\n Каждый фильтр будет обработан в описанном порядке. Не сломаный скрипт, не <code>keep;</code> не остановит обработку дальнейших скриптов.<br><br>Global sieve prefilter → Prefilter → User scripts → Postfilter → Global sieve postfilter",
|
||||
"sieve_preset_1": "Discard mail with probable dangerous file types",
|
||||
"sieve_preset_2": "Always mark the e-mail of a specific sender as seen",
|
||||
"sieve_preset_3": "Discard silently, stop all further sieve processing",
|
||||
|
@ -634,7 +634,7 @@
|
||||
"last_run": "Posledné spustenie",
|
||||
"excludes": "Vyraďuje",
|
||||
"last_run_reset": "Naplánovať ďalší",
|
||||
"sieve_info": "Môžete uchovávať viacero filtrov pre užívateľa, ale iba jeden prefilter a jeden postfilter môže byť aktívny v daný okamih.<br>\r\n Každý filter bude spracovaný v nastavenom poradí. Ani zlyhanie skriptu alebo zadržanie nezastaví spracovanie ďalších skriptov.<br>\r\n<a href=\"https://github.com/mailcow/mailcow-dockerized/blob/master/data/conf/dovecot/global_sieve_before\" target=\"_blank\">Globálny sieve prefilter</a> → Prefilter → Skripty užívateľa → Postfilter → <a href=\"https://github.com/mailcow/mailcow-dockerized/blob/master/data/conf/dovecot/global_sieve_after\" target=\"_blank\">Globálny sieve postfilter</a>",
|
||||
"sieve_info": "Môžete uchovávať viacero filtrov pre užívateľa, ale iba jeden prefilter a jeden postfilter môže byť aktívny v daný okamih.<br>\r\n Každý filter bude spracovaný v nastavenom poradí. Ani zlyhanie skriptu alebo zadržanie nezastaví spracovanie ďalších skriptov.<br><br>Globálny sieve prefilter → Prefilter → Skripty užívateľa → Postfilter → Globálny sieve postfilter",
|
||||
"sogo_visible": "Alias je viditeľný v SOGo",
|
||||
"sogo_visible_y": "Ukázať alias v SOGo",
|
||||
"sogo_visible_n": "Skryť alias v SOGo",
|
||||
|
@ -634,7 +634,7 @@
|
||||
"last_run": "Senaste körningen",
|
||||
"excludes": "Exkluderar",
|
||||
"last_run_reset": "Schemalägg nästa",
|
||||
"sieve_info": "Du kan skapa flera filter per användare, men bara ett förfilter och ett postfilter kan vara aktiva samtidigt.<br>\r\nVarje filter bearbetas i den beskrivna ordningen nedan. Varken ett misslyckat filter som kör fel, eller kommandot \"keep:\" stoppar bearbetningen av övriga filter.<br>\r\n<a href=\"https://github.com/mailcow/mailcow-dockerized/blob/master/data/conf/dovecot/global_sieve_before\" target=\"_blank\">Globala sieve förfilter</a> → Prefilter → User scripts → Postfilter → <a href=\"https://github.com/mailcow/mailcow-dockerized/blob/master/data/conf/dovecot/global_sieve_after\" target=\"_blank\">Global sieve postfilter</a>",
|
||||
"sieve_info": "Du kan skapa flera filter per användare, men bara ett förfilter och ett postfilter kan vara aktiva samtidigt.<br>\r\nVarje filter bearbetas i den beskrivna ordningen nedan. Varken ett misslyckat filter som kör fel, eller kommandot \"keep:\" stoppar bearbetningen av övriga filter.<br><br>Globala sieve förfilter → Prefilter → User scripts → Postfilter → Global sieve postfilter",
|
||||
"sogo_visible": "Visa detta alias i SOGo",
|
||||
"sogo_visible_y": "Visa alias i SOGo",
|
||||
"sogo_visible_n": "Dölj alias i SOGo",
|
||||
|
@ -328,7 +328,9 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p style="margin:10px" class="help-block"><?=$lang['mailbox']['sieve_info'];?></p>
|
||||
<div class="panel-body">
|
||||
<p class="help-block"><?=$lang['mailbox']['sieve_info'];?></p><br>
|
||||
</div>
|
||||
<!-- <div class="mass-actions-mailbox" data-actions-header="true"></div> -->
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped" id="filter_table"></table>
|
||||
@ -349,6 +351,49 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
||||
<a class="btn btn-sm btn-success" href="#" data-toggle="modal" data-target="#addFilterModalAdmin"><span class="glyphicon glyphicon-plus"></span> <?=$lang['mailbox']['add_filter'];?></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<?php
|
||||
$global_filters = mailbox('get', 'global_filter_details');
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<h5>Global Prefilter</h5>
|
||||
<form class="form-horizontal" data-cached-form="false" role="form" data-id="add_prefilter">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<textarea autocorrect="off" spellcheck="false" autocapitalize="none" class="form-control textarea-code script_data" rows="10" name="script_data" required><?=$global_filters['prefilter'];?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-10 add_filter_btns">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-sm btn-default validate_sieve" href="#"><?=$lang['add']['validate'];?></button>
|
||||
<button class="btn btn-sm btn-success add_sieve_script" data-action="add_item" data-id="add_prefilter" data-api-url='add/global-filter' data-api-attr='{"filter_type":"prefilter"}' href="#" disabled><span class="glyphicon glyphicon-check"></span> <?=$lang['admin']['save'];?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<h5>Global Postfilter</h5>
|
||||
<form class="form-horizontal" data-cached-form="false" role="form" data-id="add_postfilter">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<textarea autocorrect="off" spellcheck="false" autocapitalize="none" class="form-control textarea-code script_data" rows="10" name="script_data" required><?=$global_filters['postfilter'];?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-10 add_filter_btns">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-sm btn-default validate_sieve" href="#"><?=$lang['add']['validate'];?></button>
|
||||
<button class="btn btn-sm btn-success add_sieve_script" data-action="add_item" data-id="add_postfilter" data-api-url='add/global-filter' data-api-attr='{"filter_type":"postfilter"}' href="#" disabled><span class="glyphicon glyphicon-check"></span> <?=$lang['admin']['save'];?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -592,7 +592,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="script_data">Script:</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea autocorrect="off" spellcheck="false" autocapitalize="none" class="form-control textarea-code" rows="20" id="script_data" name="script_data" required></textarea>
|
||||
<textarea autocorrect="off" spellcheck="false" autocapitalize="none" class="form-control textarea-code script_data" rows="20" name="script_data" required></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -604,9 +604,9 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10" id="add_filter_btns">
|
||||
<button class="btn btn-default" id="validate_sieve" href="#"><?=$lang['add']['validate'];?></button>
|
||||
<button class="btn btn-success" id="add_sieve_script" data-action="add_item" data-id="add_filter" data-api-url='add/filter' data-api-attr='{}' href="#" disabled><?=$lang['admin']['add'];?></button>
|
||||
<div class="col-sm-offset-2 col-sm-10 add_filter_btns">
|
||||
<button class="btn btn-default validate_sieve" href="#"><?=$lang['add']['validate'];?></button>
|
||||
<button class="btn btn-success add_sieve_script" data-action="add_item" data-id="add_filter" data-api-url='add/filter' data-api-attr='{}' href="#" disabled><?=$lang['admin']['add'];?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
Loading…
Reference in New Issue
Block a user