From e30dfd6751d27f4edece2c58866a486b338cb7d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= Date: Tue, 23 Oct 2018 21:14:57 +0200 Subject: [PATCH] [Web] Queue manager for Postfix [Web] Add sogo_access mail attribute [Web] Allow to wipe SOGo profiles --- data/web/admin.php | 47 +++++++++++- data/web/debug.php | 2 +- data/web/edit.php | 9 +++ data/web/inc/ajax/queue_manager.php | 16 ++++ data/web/inc/functions.inc.php | 2 +- data/web/inc/functions.mailbox.inc.php | 88 ++++++++++++++++++--- data/web/inc/functions.mailq.inc.php | 72 +++++++++++++++++ data/web/inc/init_db.inc.php | 6 +- data/web/inc/prerequisites.inc.php | 1 + data/web/inc/vars.inc.php | 3 + data/web/js/admin.js | 102 +++++++++++++++++++------ data/web/js/mailbox.js | 45 +---------- data/web/json_api.php | 27 +++++++ data/web/lang/lang.de.php | 17 +++++ data/web/lang/lang.en.php | 17 +++++ data/web/user.php | 12 ++- 16 files changed, 386 insertions(+), 80 deletions(-) create mode 100644 data/web/inc/ajax/queue_manager.php create mode 100644 data/web/inc/functions.mailq.inc.php diff --git a/data/web/admin.php b/data/web/admin.php index a4d7b697..6c2e38b6 100644 --- a/data/web/admin.php +++ b/data/web/admin.php @@ -11,6 +11,7 @@ $tfa_data = get_tfa();
  • +
  • Queue manager
  • @@ -855,8 +856,52 @@ $tfa_data = get_tfa();
    - + +
    +
    +
    + Queue manager +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + + + + +
    +
    +
    +
    +
    +
    'df', 'dir' => '/var/vmail'); + $exec_fields = array('cmd' => 'system', 'task' => 'df', 'dir' => '/var/vmail'); $vmail_df = explode(',', json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true)); ?>
    diff --git a/data/web/edit.php b/data/web/edit.php index 87d563b0..971622e7 100644 --- a/data/web/edit.php +++ b/data/web/edit.php @@ -478,6 +478,7 @@ if (isset($_SESSION['mailcow_cc_role'])) { +
    @@ -573,6 +574,14 @@ if (isset($_SESSION['mailcow_cc_role'])) {
    +
    +
    +
    + + +
    +
    +
    diff --git a/data/web/inc/ajax/queue_manager.php b/data/web/inc/ajax/queue_manager.php new file mode 100644 index 00000000..8ae5cb35 --- /dev/null +++ b/data/web/inc/ajax/queue_manager.php @@ -0,0 +1,16 @@ + 'mailq')); + +if (isset($docker_return['type']['danger'])) { + echo "Cannot load mail queue: " . $docker_return['msg']; +} +else { + echo $docker_return; +} +?> diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index 4cc43ee3..43d21e03 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -1225,7 +1225,7 @@ function rspamd_ui($action, $data = null) { ); return false; } - $docker_return = docker('post', 'rspamd-mailcow', 'exec', array('cmd' => 'worker_password', 'raw' => $rspamd_ui_pass), array('Content-Type: application/json')); + $docker_return = docker('post', 'rspamd-mailcow', 'exec', array('cmd' => 'rspamd', 'task' => 'worker_password', 'raw' => $rspamd_ui_pass), array('Content-Type: application/json')); if ($docker_return_array = json_decode($docker_return, true)) { if ($docker_return_array['type'] == 'success') { $_SESSION['return'][] = array( diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 07e5a46b..4b369bfe 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -739,8 +739,10 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { array( 'force_pw_update' => strval(intval($MAILBOX_DEFAULT_ATTRIBUTES['force_pw_update'])), 'tls_enforce_in' => strval(intval($MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_in'])), - 'tls_enforce_out' => strval(intval($MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_out']))) - ); + 'tls_enforce_out' => strval(intval($MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_out'])), + 'sogo_access' => strval(intval($MAILBOX_DEFAULT_ATTRIBUTES['sogo_access'])) + ) + ); if (!is_valid_domain_name($domain)) { $_SESSION['return'][] = array( 'type' => 'danger', @@ -1881,6 +1883,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { if (!empty($is_now)) { $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int']; (int)$force_pw_update = (isset($_data['force_pw_update'])) ? intval($_data['force_pw_update']) : intval($is_now['attributes']['force_pw_update']); + (int)$sogo_access = (isset($_data['sogo_access'])) ? intval($_data['sogo_access']) : intval($is_now['attributes']['sogo_access']); $name = (!empty($_data['name'])) ? $_data['name'] : $is_now['name']; $domain = $is_now['domain']; $quota_m = (!empty($_data['quota'])) ? $_data['quota'] : ($is_now['quota'] / 1048576); @@ -2082,13 +2085,15 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { `active` = :active, `name`= :name, `quota` = :quota_b, - `attributes` = JSON_SET(`attributes`, '$.force_pw_update', :force_pw_update) + `attributes` = JSON_SET(`attributes`, '$.force_pw_update', :force_pw_update), + `attributes` = JSON_SET(`attributes`, '$.sogo_access', :sogo_access) WHERE `username` = :username"); $stmt->execute(array( ':active' => $active, ':name' => $name, ':quota_b' => $quota_b, ':force_pw_update' => $force_pw_update, + ':sogo_access' => $sogo_access, ':username' => $username )); $_SESSION['return'][] = array( @@ -2384,20 +2389,23 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $_data = $_SESSION['mailcow_cc_username']; } $exec_fields = array( - 'cmd' => 'sieve_list', + 'cmd' => 'sieve', + 'task' => 'list', 'username' => $_data ); - $filters = json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true); - $filters = array_filter(explode(PHP_EOL, $filters)); + $filters = docker('post', 'dovecot-mailcow', 'exec', $exec_fields); + $filters = array_filter(preg_split("/(\r\n|\n|\r)/",$filters)); foreach ($filters as $filter) { if (preg_match('/.+ ACTIVE/i', $filter)) { $exec_fields = array( - 'cmd' => 'sieve_print', + 'cmd' => 'sieve', + 'task' => 'print', 'script_name' => substr($filter, 0, -7), 'username' => $_data ); - $filters = json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true); - return preg_replace('/^.+\n/', '', $filters); + $script = docker('post', 'dovecot-mailcow', 'exec', $exec_fields); + // Remove first line + return preg_replace('/^.+\n/', '', $script); } } return false; @@ -3081,6 +3089,66 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ); } break; + case 'sogo_profile': + if (!is_array($_data['username'])) { + $usernames = array(); + $usernames[] = $_data['username']; + } + else { + $usernames = $_data['username']; + } + if (!isset($_SESSION['acl']['sogo_profile_reset']) || $_SESSION['acl']['sogo_profile_reset'] != "1" ) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'access_denied' + ); + return false; + } + foreach ($usernames as $username) { + if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => 'access_denied' + ); + continue; + } + $stmt = $pdo->prepare("DELETE FROM `sogo_user_profile` WHERE `c_uid` = :username"); + $stmt->execute(array( + ':username' => $username + )); + $stmt = $pdo->prepare("DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username"); + $stmt->execute(array( + ':username' => $username + )); + $stmt = $pdo->prepare("DELETE FROM `sogo_acl` WHERE `c_object` LIKE '%/" . $username . "/%' OR `c_uid` = :username"); + $stmt->execute(array( + ':username' => $username + )); + $stmt = $pdo->prepare("DELETE FROM `sogo_store` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)"); + $stmt->execute(array( + ':username' => $username + )); + $stmt = $pdo->prepare("DELETE FROM `sogo_quick_contact` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)"); + $stmt->execute(array( + ':username' => $username + )); + $stmt = $pdo->prepare("DELETE FROM `sogo_quick_appointment` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)"); + $stmt->execute(array( + ':username' => $username + )); + $stmt = $pdo->prepare("DELETE FROM `sogo_folder_info` WHERE `c_path2` = :username"); + $stmt->execute(array( + ':username' => $username + )); + $_SESSION['return'][] = array( + 'type' => 'success', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => array('sogo_profile_reset', htmlspecialchars($username)) + ); + } + break; case 'domain': if (!is_array($_data['domain'])) { $domains = array(); @@ -3119,7 +3187,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ); continue; } - $exec_fields = array('cmd' => 'maildir_cleanup', 'maildir' => $domain); + $exec_fields = array('cmd' => 'maildir', 'task' => 'cleanup', 'maildir' => $domain); $maildir_gc = json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true); if ($maildir_gc['type'] != 'success') { $_SESSION['return'][] = array( diff --git a/data/web/inc/functions.mailq.inc.php b/data/web/inc/functions.mailq.inc.php new file mode 100644 index 00000000..2bae36cc --- /dev/null +++ b/data/web/inc/functions.mailq.inc.php @@ -0,0 +1,72 @@ + 'danger', + 'log' => array(__FUNCTION__, $_action, $_data), + 'msg' => 'access_denied' + ); + return false; + } + function process_mailq_output($returned_output, $_action, $_data) { + if ($returned_output !== NULL) { + if (isset($returned_output['type']) && $returned_output['type'] == 'danger') { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array('mailq', $_action, $_data), + 'msg' => 'Error: ' . $returned_output['msg'] + ); + } + if (isset($returned_output['type']) && $returned_output['type'] == 'success') { + $_SESSION['return'][] = array( + 'type' => 'success', + 'log' => array('mailq', $_action, $_data), + 'msg' => 'queue_command_success' + ); + } + } + else { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array('mailq', $_action, $_data), + 'msg' => 'unknown' + ); + } + } + global $lang; + switch ($_action) { + case 'delete': + if (!is_array($_data['qid'])) { + $qids = array(); + $qids[] = $_data['qid']; + } + else { + $qids = $_data['qid']; + } + $docker_return = docker('post', 'postfix-mailcow', 'exec', array('cmd' => 'mailq', 'task' => 'delete', 'items' => $qids)); + process_mailq_output(json_decode($docker_return, true), $_action, $_data); + break; + case 'edit': + if (in_array($_data['action'], array('hold', 'unhold', 'deliver'))) { + if (!is_array($_data['qid'])) { + $qids = array(); + $qids[] = $_data['qid']; + } + else { + $qids = $_data['qid']; + } + if (!empty($qids)) { + $docker_return = docker('post', 'postfix-mailcow', 'exec', array('cmd' => 'mailq', 'task' => $_data['action'], 'items' => $qids)); + process_mailq_output(json_decode($docker_return, true), $_action, $_data); + } + } + if (in_array($_data['action'], array('flush', 'super_delete'))) { + $docker_return = docker('post', 'postfix-mailcow', 'exec', array('cmd' => 'mailq', 'task' => $_data['action'])); + process_mailq_output(json_decode($docker_return, true), $_action, $_data); + } + break; + case 'get': + // todo: move get from json_api here + break; + } +} diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index f2db0f1a..388772b1 100644 --- a/data/web/inc/init_db.inc.php +++ b/data/web/inc/init_db.inc.php @@ -3,7 +3,7 @@ function init_db_schema() { try { global $pdo; - $db_version = "07102018_1502"; + $db_version = "22102018_1502"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -291,6 +291,7 @@ function init_db_schema() { "delimiter_action" => "TINYINT(1) NOT NULL DEFAULT '1'", "syncjobs" => "TINYINT(1) NOT NULL DEFAULT '1'", "eas_reset" => "TINYINT(1) NOT NULL DEFAULT '1'", + "sogo_profile_reset" => "TINYINT(1) NOT NULL DEFAULT '1'", "quarantine" => "TINYINT(1) NOT NULL DEFAULT '1'", ), "keys" => array( @@ -963,7 +964,8 @@ DELIMITER ;'; // Migrate tls_enforce_* options and add force_pw_update attribute $stmt = $pdo->query("UPDATE `mailbox` SET `attributes` = '{}' WHERE `attributes` IS NULL;"); - $stmt = $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.force_pw_update', 0) WHERE JSON_EXTRACT(`attributes`, '$.force_pw_update') IS NULL;"); + $stmt = $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.force_pw_update', \"0\") WHERE JSON_EXTRACT(`attributes`, '$.force_pw_update') IS NULL;"); + $stmt = $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.sogo_access', \"1\") WHERE JSON_EXTRACT(`attributes`, '$.sogo_access') IS NULL;"); foreach($tls_options as $tls_user => $tls_options) { $stmt = $pdo->prepare("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.tls_enforce_in', :tls_enforce_in), `attributes` = JSON_SET(`attributes`, '$.tls_enforce_out', :tls_enforce_out) diff --git a/data/web/inc/prerequisites.inc.php b/data/web/inc/prerequisites.inc.php index 4296c837..9170080c 100644 --- a/data/web/inc/prerequisites.inc.php +++ b/data/web/inc/prerequisites.inc.php @@ -142,6 +142,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.quarantine.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.policy.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.dkim.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.fwdhost.inc.php'; +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.mailq.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.ratelimit.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.relayhost.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.rsettings.inc.php'; diff --git a/data/web/inc/vars.inc.php b/data/web/inc/vars.inc.php index e402055b..c9cda357 100644 --- a/data/web/inc/vars.inc.php +++ b/data/web/inc/vars.inc.php @@ -139,3 +139,6 @@ $MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_out'] = false; // Force password change on next login (only allows login to mailcow UI) $MAILBOX_DEFAULT_ATTRIBUTES['force_pw_update'] = false; + +// Force password change on next login (only allows login to mailcow UI) +$MAILBOX_DEFAULT_ATTRIBUTES['sogo_access'] = true; diff --git a/data/web/js/admin.js b/data/web/js/admin.js index d5ea7f67..4ee9d886 100644 --- a/data/web/js/admin.js +++ b/data/web/js/admin.js @@ -5,18 +5,6 @@ jQuery(function($){ var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="}; function escapeHtml(n){return String(n).replace(/[&<>"'`=\/]/g,function(n){return entityMap[n]})} function humanFileSize(i){if(Math.abs(i)<1024)return i+" B";var B=["KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"],e=-1;do{i/=1024,++e}while(Math.abs(i)>=1024&&e'; item.chkbox = ''; }); + } else if (table == 'queuetable') { + $.each(data, function (i, item) { + item.chkbox = ''; + item.recipients = JSON.stringify(item.recipients); + }); } else if (table == 'forwardinghoststable') { $.each(data, function (i, item) { item.action = '
    ' + @@ -206,6 +261,7 @@ jQuery(function($){ draw_admins(); draw_fwd_hosts(); draw_relayhosts(); + draw_queue(); // Relayhost $('#testRelayhostModal').on('show.bs.modal', function (e) { $('#test_relayhost_result').text("-"); @@ -225,9 +281,9 @@ jQuery(function($){ dataType: 'text', data: $('#test_relayhost_form').serialize(), complete: function (data) { - $('#test_relayhost_result').html(data.responseText); - $('#test_relayhost').prop("disabled",false); - $('#test_relayhost').text(prev); + $('#test_relayhost_result').html(data.responseText); + $('#test_relayhost').prop("disabled",false); + $('#test_relayhost').text(prev); } }); }) diff --git a/data/web/js/mailbox.js b/data/web/js/mailbox.js index ae99ad3d..3671fa40 100644 --- a/data/web/js/mailbox.js +++ b/data/web/js/mailbox.js @@ -58,7 +58,6 @@ $(document).ready(function() { $(this.$domain).closest("select").selectpicker(); } }); - // Auto-fill domain quota when adding new domain auto_fill_quota = function(domain) { $.get("/api/v1/get/domain/" + domain, function(data){ @@ -80,7 +79,6 @@ $(document).ready(function() { auto_fill_quota($('#addSelectDomain').val()); }); auto_fill_quota($('#addSelectDomain').val()); - $(".generate_password").click(function( event ) { event.preventDefault(); $('[data-hibp]').trigger('input'); @@ -90,7 +88,6 @@ $(document).ready(function() { $(this).closest("form").find("input[name='password']").val(random_passwd); $(this).closest("form").find("input[name='password2']").val(random_passwd); }); - $(".goto_checkbox").click(function( event ) { $("form[data-id='add_alias'] .goto_checkbox").not(this).prop('checked', false); if ($("form[data-id='add_alias'] .goto_checkbox:checked").length > 0) { @@ -108,7 +105,6 @@ $(document).ready(function() { $("#textarea_alias_goto").removeAttr('disabled'); } }); - // Log modal $('#syncjobLogModal').on('show.bs.modal', function(e) { var syncjob_id = $(e.relatedTarget).data('syncjob-id'); @@ -124,7 +120,6 @@ $(document).ready(function() { } }); }); - // Log modal $('#dnsInfoModal').on('show.bs.modal', function(e) { var domain = $(e.relatedTarget).data('domain'); @@ -141,13 +136,11 @@ $(document).ready(function() { } }); }); - // Sieve data modal $('#sieveDataModal').on('show.bs.modal', function(e) { var sieveScript = $(e.relatedTarget).data('sieve-script'); $(e.currentTarget).find('#sieveDataText').html('
    ' + sieveScript + '
    '); }); - // Set line numbers for textarea $("#script_data").numberedtextarea({allowTabChar: true}); // Disable submit button on script change @@ -155,7 +148,6 @@ $(document).ready(function() { $('#add_filter_btns > #add_item').attr({"disabled": true}); $('#validation_msg').html('-'); }); - // Validate script data $("#validate_sieve").click(function( event ) { event.preventDefault(); @@ -185,21 +177,8 @@ $(document).ready(function() { }); jQuery(function($){ // http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery - var entityMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '/': '/', - '`': '`', - '=': '=' - }; - function escapeHtml(string) { - return String(string).replace(/[&<>"'`=\/]/g, function (s) { - return entityMap[s]; - }); - } + var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="}; + function escapeHtml(n){return String(n).replace(/[&<>"'`=\/]/g,function(n){return entityMap[n]})} if (localStorage.getItem("current_page") === null) { var current_page = {}; } else { @@ -210,23 +189,7 @@ jQuery(function($){ var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return re.test(email); } - // Calculation human readable file sizes - function humanFileSize(bytes) { - if(Math.abs(bytes) < 1024) { - return bytes + ' B'; - } - var units = ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB']; - var u = -1; - do { - bytes /= 1024; - ++u; - } while(Math.abs(bytes) >= 1024 && u < units.length - 1); - return bytes.toFixed(1)+' '+units[u]; - } - function unix_time_format(tm) { - var date = new Date(tm ? tm * 1000 : 0); - return date.toLocaleString(); - } + function humanFileSize(i){if(Math.abs(i)<1024)return i+" B";var B=["KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"],e=-1;do{i/=1024,++e}while(Math.abs(i)>=1024&&e 'mailq', 'task' => 'list')); + $lines = 0; + // Hard limit to 1000 items + foreach (preg_split("/((\r?\n)|(\r\n?))/", $mailq_lines) as $mailq_item) if ($lines++ < 1000) { + if (empty($mailq_item) || $mailq_item == '1') { + continue; + } + $line[] = json_decode($mailq_item, true); + } + if (!isset($line) || empty($line)) { + echo '{}'; + } + else { + echo json_encode($line); + } + break; + case "rl-domain": switch ($object) { case "all": @@ -974,6 +992,9 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u case "filter": process_delete_return(mailbox('delete', 'filter', array('id' => $items))); break; + case "mailq": + process_delete_return(mailq('delete', array('qid' => $items))); + break; case "qitem": process_delete_return(quarantine('delete', array('id' => $items))); break; @@ -1017,6 +1038,9 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u case "eas_cache": process_delete_return(mailbox('delete', 'eas_cache', array('username' => $items))); break; + case "sogo_profile": + process_delete_return(mailbox('delete', 'sogo_profile', array('username' => $items))); + break; case "domain-admin": process_delete_return(domain_admin('delete', array('username' => $items))); break; @@ -1088,6 +1112,9 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u case "quarantine": process_edit_return(quarantine('edit', $attr)); break; + case "mailq": + process_edit_return(mailq('edit', array_merge(array('qid' => $items), $attr))); + break; case "time_limited_alias": process_edit_return(mailbox('edit', 'time_limited_alias', array_merge(array('address' => $items), $attr))); break; diff --git a/data/web/lang/lang.de.php b/data/web/lang/lang.de.php index 8b63c45e..eff93696 100644 --- a/data/web/lang/lang.de.php +++ b/data/web/lang/lang.de.php @@ -31,6 +31,7 @@ $lang['danger']['yotp_verification_failed'] = "Yubico OTP Verifizierung fehlgesc $lang['danger']['ip_list_empty'] = "Liste erlaubter IPs darf nicht leer sein"; $lang['danger']['rspamd_ui_pw_length'] = "Rspamd UI Passwort muss mindestens 6 Zeichen lang sein"; $lang['success']['rspamd_ui_pw_set'] = "Rspamd UI Passwort wurde gesetzt"; +$lang['success']['queue_command_success'] = "Queue-Aufgabe erfolgreich ausgeführt"; $lang['danger']['unknown'] = "Ein unbekannter Fehler trat auf"; $lang['danger']['malformed_username'] = "Benutzername hat falsches Format"; $lang['info']['awaiting_tfa_confirmation'] = "Warte auf TFA Verifizierung"; @@ -134,6 +135,7 @@ $lang['success']['domain_admin_removed'] = 'Domain-Administrator %s wurde entfer $lang['success']['admin_removed'] = 'Administrator %s wurde entfernt'; $lang['success']['mailbox_removed'] = 'Mailbox %s wurde entfernt'; $lang['success']['eas_reset'] = "ActiveSync Gerät des Benutzers %s wurden zurückgesetzt"; +$lang['success']['sogo_profile_reset'] = "ActiveSync Gerät des Benutzers %s wurden zurückgesetzt"; $lang['success']['resource_removed'] = 'Ressource %s wurde entfernt'; $lang['warning']['cannot_delete_self'] = 'Kann derzeit eingeloggten Benutzer nicht entfernen'; $lang['warning']['no_active_admin'] = 'Kann letzten aktiven Administrator nicht deaktivieren'; @@ -221,10 +223,15 @@ $lang['user']['tag_in_none'] = 'Nichts tun'; $lang['user']['tag_help_explain'] = 'Als Unterordner: Es wird ein Ordner mit dem Namen des Tags unterhalb der Inbox erstellt ("INBOX/Facebook").
    In Betreff: Der Name des Tags wird dem Betreff angefügt, etwa "[Facebook] Meine Neuigkeiten".'; $lang['user']['tag_help_example'] = 'Beispiel für eine getaggte E-Mail-Adresse: ich+Facebook@example.org'; + $lang['user']['eas_reset'] = 'ActiveSync Geräte-Cache zurücksetzen'; $lang['user']['eas_reset_now'] = 'Jetzt zurücksetzen'; $lang['user']['eas_reset_help'] = 'In vielen Fällen kann ein ActiveSync Profil durch das Zurücksetzen des Caches repariert werden.
    Vorsicht: Alle Elemente werden erneut heruntergeladen!'; +$lang['user']['sogo_profile_reset'] = 'SOGo Profil zurücksetzen'; +$lang['user']['sogo_profile_reset_now'] = 'Profil jetzt zurücksetzen'; +$lang['user']['sogo_profile_reset_help'] = 'Das Profil wird zuzüglich aller Daten unwiederbringlich gelöscht.'; + $lang['user']['encryption'] = 'Verschlüsselung'; $lang['user']['username'] = 'Benutzername'; $lang['user']['last_run'] = 'Letzte Ausführung'; @@ -331,6 +338,8 @@ $lang['edit']['target_address'] = 'Ziel-Adresse(n) (getrennt durch Komma) $lang['edit']['active'] = 'Aktiv'; $lang['edit']['force_pw_update'] = 'Erzwinge Passwortänderung bei nächstem Login'; $lang['edit']['force_pw_update_info'] = 'Dem Benutzer wird lediglich der Zugang zur mailcow UI ermöglicht.'; +$lang['edit']['sogo_access'] = 'SOGo Zugriffsrecht'; +$lang['edit']['sogo_access_info'] = 'Zugriff auf SOGo erlauben oder verbieten. Diese Einstellung hat weder Einfluss auf den Zugang sonstiger Dienste noch entfernt sie ein vorhandenes SOGo Benutzerprofil.'; $lang['edit']['target_domain'] = 'Ziel-Domain:'; $lang['edit']['password'] = 'Passwort:'; $lang['edit']['password_repeat'] = 'Passwort (Wiederholung):'; @@ -367,6 +376,7 @@ $lang['acl']['spam_policy'] = 'Blacklist/Whitelist'; $lang['acl']['delimiter_action'] = 'Delimiter Aktionen (tags)'; $lang['acl']['syncjobs'] = 'Sync Jobs'; $lang['acl']['eas_reset'] = 'EAS-Cache zurücksetzen'; +$lang['acl']['sogo_profile_reset'] = 'SOGo Profil zurücksetzen'; $lang['acl']['quarantine'] = 'Quarantäne'; $lang['acl']['login_as'] = 'Einloggen als Mailbox-Benutzer'; $lang['acl']['bcc_maps'] = 'BCC Maps'; @@ -520,6 +530,13 @@ $lang['admin']['rsettings_preset_2'] = 'Spam an Postmaster-Addressen nicht block $lang['admin']['rsettings_insert_preset'] = 'Beispiel "%s" laden'; $lang['admin']['rsetting_add_rule'] = 'Regel hinzufügen'; $lang['admin']['admin_domains'] = 'Domain-Zuweisungen'; +$lang['admin']['queue_ays'] = 'Soll die derzeitige Queue wirklich komplett bereinigt werden?'; +$lang['admin']['arrival_time'] = 'Ankunftszeit (Serverzeit)'; +$lang['admin']['message_size'] = 'Nachrichtengröße'; +$lang['admin']['sender'] = 'Sender'; +$lang['admin']['recipients'] = 'Empfänger'; +$lang['admin']['flush_queue'] = 'Flush Queue'; +$lang['admin']['delete_queue'] = 'Alle löschen'; $lang['admin']['domain_admins'] = 'Domain-Administratoren'; $lang['admin']['username'] = 'Benutzername'; $lang['admin']['edit'] = 'Bearbeiten'; diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php index 9cdf15da..30cf6819 100644 --- a/data/web/lang/lang.en.php +++ b/data/web/lang/lang.en.php @@ -31,6 +31,7 @@ $lang['danger']['yotp_verification_failed'] = "Yubico OTP verification failed: % $lang['danger']['ip_list_empty'] = "List of allowed IPs cannot be empty"; $lang['danger']['rspamd_ui_pw_length'] = "Rspamd UI password should be at least 6 chars long"; $lang['success']['rspamd_ui_pw_set'] = "Rspamd UI password successfully set"; +$lang['success']['queue_command_success'] = "Queue command completed successfully"; $lang['danger']['unknown'] = "An unknown error occured"; $lang['danger']['malformed_username'] = "Malformed username"; $lang['info']['awaiting_tfa_confirmation'] = "Awaiting TFA confirmation"; @@ -137,6 +138,7 @@ $lang['success']['domain_admin_removed'] = "Domain administrator %s has been rem $lang['success']['admin_removed'] = "Administrator %s has been removed"; $lang['success']['mailbox_removed'] = "Mailbox %s has been removed"; $lang['success']['eas_reset'] = "ActiveSync devices for user %s were reset"; +$lang['success']['sogo_profile_reset'] = "SOGo profile for user %s was reset"; $lang['success']['resource_removed'] = "Resource %s has been removed"; $lang['warning']['cannot_delete_self'] = "Cannot delete logged in user"; $lang['warning']['no_active_admin'] = "Cannot deactivate last active admin"; @@ -223,10 +225,15 @@ $lang['user']['tag_in_none'] = 'Do nothing'; $lang['user']['tag_help_explain'] = 'In subfolder: a new subfolder named after the tag will be created below INBOX ("INBOX/Facebook").
    In subject: the tags name will be prepended to the mails subject, example: "[Facebook] My News".'; $lang['user']['tag_help_example'] = 'Example for a tagged email address: me+Facebook@example.org'; + $lang['user']['eas_reset'] = 'Reset ActiveSync device cache'; $lang['user']['eas_reset_now'] = 'Reset now'; $lang['user']['eas_reset_help'] = 'In many cases a device cache reset will help to recover a broken ActiveSync profile.
    Attention: All elements will be redownloaded!'; +$lang['user']['sogo_profile_reset'] = 'Reset SOGo profile'; +$lang['user']['sogo_profile_reset_now'] = 'Reset profile now'; +$lang['user']['sogo_profile_reset_help'] = 'This will destroy a users SOGo profile and delete all data irretrievable.'; + $lang['user']['encryption'] = 'Encryption'; $lang['user']['username'] = 'Username'; $lang['user']['last_run'] = 'Last run'; @@ -342,6 +349,8 @@ $lang['edit']['target_address'] = 'Goto address/es (comma-separated)
    +
    +
    :
    @@ -232,6 +234,14 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
    +
    +
    :
    +
    + +

    +
    +
    +
    @@ -392,7 +402,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
  • -
  • +