public
nobgit
read
NobMail
Based on mailcow: dockerized
Languages
Repository composition by tracked source files.
PHP
49%
JavaScript
35%
HTML
9%
CSS
4%
Shell
2%
Python
1%
Lua
0%
Perl
0%
Ruby
0%
SCSS
0%
Create file
Wiki Documentation
Clone
https://nobgit.com/orgs/nobgit/nobmail.git
ssh://[email protected]:2222/orgs/nobgit/nobmail.git
Commit
[Web] Fix symbol options encoding in rspamd item view [Web] Feature: Allow to view mailq item content via postcat [Web] Fix Rspamd not drawing
21a153c2
data/web/inc/ajax/queue_manager.php | 16 ----
data/web/inc/functions.mailq.inc.php | 150 ++++++++++++++++++++---------------
data/web/js/site/admin.js | 20 +++++
data/web/js/site/debug.js | 32 +++++---
data/web/json_api.php | 9 +++
data/web/lang/lang.de.json | 2 +
data/web/lang/lang.en.json | 2 +
data/web/mailbox.php | 1 +
data/web/modals/admin.php | 15 ++++
9 files changed, 153 insertions(+), 94 deletions(-)
delete mode 100644 data/web/inc/ajax/queue_manager.php
Diff
diff --git a/data/web/inc/ajax/queue_manager.php b/data/web/inc/ajax/queue_manager.php
deleted file mode 100644
index 8ae5cb35..00000000
--- a/data/web/inc/ajax/queue_manager.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-session_start();
-require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
-header('Content-Type: text/plain');
-if (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != 'admin') {
- exit();
-}
-$docker_return = docker('post', 'postfix-mailcow', 'exec', array('cmd' => '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.mailq.inc.php b/data/web/inc/functions.mailq.inc.php
index 24de47be..b980d7c8 100644
--- a/data/web/inc/functions.mailq.inc.php
+++ b/data/web/inc/functions.mailq.inc.php
@@ -10,64 +10,98 @@ function mailq($_action, $_data = null) {
}
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 ($_action == 'cat') {
+ logger(array('return' => array(
+ array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_data),
+ 'msg' => 'queue_cat_success'
+ )
+ )));
+ return $returned_output;
}
- if (isset($returned_output['type']) && $returned_output['type'] == 'success') {
- $_SESSION['return'][] = array(
- 'type' => 'success',
- 'log' => array('mailq', $_action, $_data),
- 'msg' => 'queue_command_success'
- );
+ else {
+ if (isset($returned_output['type']) && $returned_output['type'] == 'danger') {
+ $_SESSION['return'][] = array(
+ 'type' => 'danger',
+ 'log' => array(__FUNCTION__, $_action, $_data),
+ 'msg' => 'Error: ' . $returned_output['msg']
+ );
+ }
+ if (isset($returned_output['type']) && $returned_output['type'] == 'success') {
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $_action, $_data),
+ 'msg' => 'queue_command_success'
+ );
+ }
}
}
else {
$_SESSION['return'][] = array(
'type' => 'danger',
- 'log' => array('mailq', $_action, $_data),
+ 'log' => array(__FUNCTION__, $_action, $_data),
'msg' => 'unknown'
);
}
}
global $lang;
- switch ($_action) {
- case 'get':
- $mailq_lines = docker('post', 'postfix-mailcow', 'exec', array('cmd' => 'mailq', 'task' => 'list'));
- $lines = 0;
- // Hard limit to 10000 items
- foreach (preg_split("/((\r?\n)|(\r\n?))/", $mailq_lines) as $mailq_item) if ($lines++ < 10000) {
- if (empty($mailq_item) || $mailq_item == '1') {
- continue;
- }
- $mq_line = json_decode($mailq_item, true);
- if ($mq_line !== NULL) {
- $rcpts = array();
- foreach ($mq_line['recipients'] as $rcpt) {
- if (isset($rcpt['delay_reason'])) {
- $rcpts[] = $rcpt['address'] . ' (' . $rcpt['delay_reason'] . ')';
- }
- else {
- $rcpts[] = $rcpt['address'];
- }
+ if ($_action == 'get') {
+ $mailq_lines = docker('post', 'postfix-mailcow', 'exec', array('cmd' => 'mailq', 'task' => 'list'));
+ $lines = 0;
+ // Hard limit to 10000 items
+ foreach (preg_split("/((\r?\n)|(\r\n?))/", $mailq_lines) as $mailq_item) if ($lines++ < 10000) {
+ if (empty($mailq_item) || $mailq_item == '1') {
+ continue;
+ }
+ $mq_line = json_decode($mailq_item, true);
+ if ($mq_line !== NULL) {
+ $rcpts = array();
+ foreach ($mq_line['recipients'] as $rcpt) {
+ if (isset($rcpt['delay_reason'])) {
+ $rcpts[] = $rcpt['address'] . ' (' . $rcpt['delay_reason'] . ')';
}
- if (!empty($rcpts)) {
- $mq_line['recipients'] = $rcpts;
+ else {
+ $rcpts[] = $rcpt['address'];
}
- $line[] = $mq_line;
}
+ if (!empty($rcpts)) {
+ $mq_line['recipients'] = $rcpts;
+ }
+ $line[] = $mq_line;
}
- if (!isset($line) || empty($line)) {
- return '{}';
- }
- else {
- return json_encode($line);
- }
- break;
- case 'delete':
+ }
+ if (!isset($line) || empty($line)) {
+ return '{}';
+ }
+ else {
+ return json_encode($line);
+ }
+ }
+ elseif ($_action == '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);
+ }
+ elseif ($_action == 'cat') {
+ 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' => 'cat', 'items' => $qids));
+ return process_mailq_output($docker_return, $_action, $_data);
+ }
+ elseif ($_action == 'edit') {
+ if (in_array($_data['action'], array('hold', 'unhold', 'deliver'))) {
if (!is_array($_data['qid'])) {
$qids = array();
$qids[] = $_data['qid'];
@@ -75,30 +109,14 @@ function mailq($_action, $_data = null) {
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']));
+ 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);
}
- break;
- case 'get':
- // todo: move get from json_api here
- break;
+ }
+ 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);
+ }
}
}
diff --git a/data/web/js/site/admin.js b/data/web/js/site/admin.js
index c0428deb..6ca76635 100644
--- a/data/web/js/site/admin.js
+++ b/data/web/js/site/admin.js
@@ -248,6 +248,7 @@ jQuery(function($){
}},
{"name":"sender","title":lang.sender, "type": "text","breakpoints":"xs sm"},
{"name":"recipients","title":lang.recipients, "type": "text","style":{"word-break":"break-all","min-width":"300px"},"breakpoints":"xs sm md"},
+ {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"220px","width":"220px"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
],
"rows": $.ajax({
dataType: 'json',
@@ -301,6 +302,9 @@ jQuery(function($){
return escapeHtml(i);
});
item.recipients = rcpts.join('<hr style="margin:1px!important">');
+ item.action = '<div class="btn-group">' +
+ '<a href="#" data-toggle="modal" data-target="#showQueuedMsg" data-queue-id="' + encodeURI(item.queue_id) + '" class="btn btn-xs btn-default">' + lang.queue_show_message + '</a>' +
+ '</div>';
});
} else if (table == 'forwardinghoststable') {
$.each(data, function (i, item) {
@@ -413,6 +417,22 @@ jQuery(function($){
$('#transport_type').val(button.data('transport-type'));
}
})
+ // Queue item
+ $('#showQueuedMsg').on('show.bs.modal', function (e) {
+ $('#queue_msg_content').text("Loading...");
+ button = $(e.relatedTarget)
+ if (button != null) {
+ $('#queue_id').text(button.data('queue-id'));
+ }
+ $.ajax({
+ type: 'GET',
+ url: '/api/v1/get/postcat/' + button.data('queue-id'),
+ dataType: 'text',
+ complete: function (data) {
+ $('#queue_msg_content').text(data.responseText);
+ }
+ });
+ })
$('#test_transport').on('click', function (e) {
e.preventDefault();
prev = $('#test_transport').text();
diff --git a/data/web/js/site/debug.js b/data/web/js/site/debug.js
index df94e2f8..557e431c 100644
--- a/data/web/js/site/debug.js
+++ b/data/web/js/site/debug.js
@@ -404,7 +404,7 @@ jQuery(function($){
function rspamd_pie_graph() {
$.ajax({
url: '/api/v1/get/rspamd/actions',
- async: false,
+ async: true,
success: function(data){
var total = 0;
@@ -438,17 +438,25 @@ jQuery(function($){
}
}
};
-
var chartcanvas = document.getElementById('rspamd_donut');
-
Chart.plugins.register('ChartDataLabels');
-
- var chart = new Chart(chartcanvas.getContext("2d"), {
- plugins: [ChartDataLabels],
- type: 'doughnut',
- data: graphdata,
- options: options
- });
+ if(typeof chart == 'undefined') {
+ chart = new Chart(chartcanvas.getContext("2d"), {
+ plugins: [ChartDataLabels],
+ type: 'doughnut',
+ data: graphdata,
+ options: options
+ });
+ }
+ else {
+ chart.destroy();
+ chart = new Chart(chartcanvas.getContext("2d"), {
+ plugins: [ChartDataLabels],
+ type: 'doughnut',
+ data: graphdata,
+ options: options
+ });
+ }
}
});
}
@@ -534,7 +542,7 @@ jQuery(function($){
}
var str = '<strong>' + key + '</strong> ' + sym.score_formatted;
if (sym.options) {
- str += ' [' + sym.options.join(", ") + "]";
+ str += ' [' + escapeHtml(sym.options.join(", ")) + "]";
}
return str
}).join('<br>\n');
@@ -703,7 +711,7 @@ jQuery(function($){
draw_rspamd_history();
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var target = $(e.target).attr("href");
- if ((target == '#tab-rspamd-history')) {
+ if (target == '#tab-rspamd-history') {
rspamd_pie_graph();
}
});
diff --git a/data/web/json_api.php b/data/web/json_api.php
index f122dd2b..a05497a8 100644
--- a/data/web/json_api.php
+++ b/data/web/json_api.php
@@ -375,6 +375,15 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
break;
}
break;
+
+ case "postcat":
+ switch ($object) {
+ default:
+ $data = mailq('cat', array('qid' => $object));
+ echo $data;
+ break;
+ }
+ break;
case "global_filters":
$global_filters = mailbox('get', 'global_filter_details');
diff --git a/data/web/lang/lang.de.json b/data/web/lang/lang.de.json
index e6c39fd2..0598d135 100644
--- a/data/web/lang/lang.de.json
+++ b/data/web/lang/lang.de.json
@@ -231,6 +231,7 @@
"queue_manager": "Queue Manager",
"queue_unban": "Entsperren einreihen",
"queue_unhold_mail": "Freigeben",
+ "queue_show_message": "Nachricht anzeigen",
"quota_notification_html": "Benachrichtigungs-E-Mail Inhalt:<br><small>Leer lassen, um Standard-Template wiederherzustellen.</small>",
"quota_notification_sender": "Benachrichtigungs-E-Mail Absender",
"quota_notification_subject": "Benachrichtigungs-E-Mail Betreff",
@@ -707,6 +708,7 @@
"tls_map_policy": "Richtlinie",
"tls_policy_maps": "TLS-Richtlinien",
"tls_policy_maps_info": "Nachstehende Richtlinien erzwingen TLS-Transportregeln unabhängig von TLS-Richtlinieneinstellungen eines Benutzers.<br>\r\n Für weitere Informationen zur Syntax sollte <a href=\"http://www.postfix.org/postconf.5.html#smtp_tls_policy_maps\" target=\"_blank\">die \"smtp_tls_policy_maps\" Dokumentation</a> konsultiert werden.",
+ "tls_policy_maps_enforced_tls": "Die Richtlinien überschreiben auch das Verhalten für Mailbox-Benutzer, die für ausgehende Verbindungen TLS erzwingen. Ist keine Policy nachstehend konfiguriert, richtet sich der Standard für diese Benutzer sich nach den Werten <code>smtp_tls_mandatory_protocols</code> und <code>smtp_tls_mandatory_ciphers</code>.",
"tls_policy_maps_long": "Ausgehende TLS-Richtlinien",
"toggle_all": "Alle",
"username": "Benutzername",
diff --git a/data/web/lang/lang.en.json b/data/web/lang/lang.en.json
index 11a2b7d3..b21c3924 100644
--- a/data/web/lang/lang.en.json
+++ b/data/web/lang/lang.en.json
@@ -230,6 +230,7 @@
"queue_manager": "Queue manager",
"queue_unban": "queue unban",
"queue_unhold_mail": "Unhold",
+ "queue_show_message": "Show message",
"quota_notification_html": "Notification email template:<br><small>Leave empty to restore default template.</small>",
"quota_notification_sender": "Notification email sender",
"quota_notification_subject": "Notification email subject",
@@ -706,6 +707,7 @@
"tls_map_policy": "Policy",
"tls_policy_maps": "TLS policy maps",
"tls_policy_maps_info": "This policy map overrides outgoing TLS transport rules independently of a users TLS policy settings.<br>\r\n Please check <a href=\"http://www.postfix.org/postconf.5.html#smtp_tls_policy_maps\" target=\"_blank\">the \"smtp_tls_policy_maps\" docs</a> for further information.",
+ "tls_policy_maps_enforced_tls": "These policies will also override the behaviour for mailbox users that enforce outgoing TLS connections. If no policy exists below, these users will apply the default values specified as <code>smtp_tls_mandatory_protocols</code> and <code>smtp_tls_mandatory_ciphers</code>.",
"tls_policy_maps_long": "Outgoing TLS policy map overrides",
"toggle_all": "Toggle all",
"username": "Username",
diff --git a/data/web/mailbox.php b/data/web/mailbox.php
index 366aea09..cabeec4b 100644
--- a/data/web/mailbox.php
+++ b/data/web/mailbox.php
@@ -498,6 +498,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
</div>
</div>
<p style="margin:10px" class="help-block"><?=$lang['mailbox']['tls_policy_maps_info'];?></p>
+ <p style="margin:10px" class="help-block"><?=$lang['mailbox']['tls_policy_maps_enforced_tls'];?></p>
<!-- <div class="mass-actions-mailbox" data-actions-header="true"></div> -->
<div class="table-responsive">
<table class="table table-striped" id="tls_policy_table"></table>
diff --git a/data/web/modals/admin.php b/data/web/modals/admin.php
index d0167700..9f23c652 100644
--- a/data/web/modals/admin.php
+++ b/data/web/modals/admin.php
@@ -206,6 +206,21 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
</div>
</div>
</div><!-- test transport modal -->
+<!-- show queue item modal -->
+<div class="modal fade" id="showQueuedMsg" tabindex="-1" role="dialog" aria-hidden="true">
+ <div class="modal-dialog modal-lg">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
+ <h3 class="modal-title"><span class="glyphicon glyphicon-hourglass" style="font-size:18px"></span> ID <span id="queue_id"></span></h3>
+ </div>
+ <div class="modal-body">
+ <pre id="queue_msg_content">
+ </pre>
+ </div>
+ </div>
+ </div>
+</div><!-- show queue item modal -->
<!-- priv key modal -->
<div class="modal fade" id="showDKIMprivKey" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">