diff --git a/.gitignore b/.gitignore
index 0d081fc4..b945f8cf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,4 +21,3 @@ data/conf/nginx/*.conf
data/conf/nginx/*.custom
data/conf/nginx/*.bak
data/conf/dovecot/extra.conf
-data/conf/rspamd/custom/*
diff --git a/data/web/admin.php b/data/web/admin.php
index 0d7c6466..e1fe74be 100644
--- a/data/web/admin.php
+++ b/data/web/admin.php
@@ -8,26 +8,8 @@ $tfa_data = get_tfa();
?>
@@ -58,7 +40,7 @@ $tfa_data = get_tfa();
@@ -96,6 +78,42 @@ $tfa_data = get_tfa();
+
+
+
=$lang['admin']['domain_admins'];?>
@@ -121,17 +139,15 @@ $tfa_data = get_tfa();
-
-
-
+
-
@@ -381,6 +395,43 @@ $tfa_data = get_tfa();
+
+
+
Quarantäne
+
+
+
+
+
+
=$lang['admin']['customize'];?>
@@ -449,10 +500,29 @@ $tfa_data = get_tfa();
endforeach;
?>
-
-
-
-
+
+
+
+
+
+
+
+
@@ -460,111 +530,6 @@ $tfa_data = get_tfa();
-
-
-
Postfix
-
-
-
-
-
-
-
-
-
-
-
-
-
Dovecot
-
-
-
-
-
-
-
-
-
-
-
-
-
SOGo
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Fail2ban
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Rspamd history
-
-
-
-
-
-
-
-
-
-
-
-
-
Autodiscover
-
-
-
-
-
-
-
-
-
-
li{float:none}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px}.collapse.in{display:block!important}.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}}
\ No newline at end of file
diff --git a/data/web/css/debug.css b/data/web/css/debug.css
new file mode 100644
index 00000000..585d1905
--- /dev/null
+++ b/data/web/css/debug.css
@@ -0,0 +1,37 @@
+table.footable>tbody>tr.footable-empty>td {
+ font-size:15px !important;
+ font-style:italic;
+}
+.pagination a {
+ text-decoration: none !important;
+}
+.panel panel-default {
+ overflow: visible !important;
+}
+.table-responsive {
+ overflow: visible !important;
+}
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ overflow-x: scroll !important;
+ }
+}
+.footer-add-item {
+ display:block;
+ text-align: center;
+ font-style: italic;
+ padding: 10px;
+ background: #F5F5F5;
+}
+@media (min-width: 992px) {
+ .container {
+ width: 80%;
+ }
+}
+.mass-actions-debug {
+ user-select: none;
+ padding:10px 0 10px 10px;
+}
+.inputMissingAttr {
+ border-color: #FF4136;
+}
\ No newline at end of file
diff --git a/data/web/css/quarantaine.css b/data/web/css/quarantaine.css
new file mode 100644
index 00000000..7a5ee761
--- /dev/null
+++ b/data/web/css/quarantaine.css
@@ -0,0 +1,37 @@
+table.footable>tbody>tr.footable-empty>td {
+ font-size:15px !important;
+ font-style:italic;
+}
+.pagination a {
+ text-decoration: none !important;
+}
+.panel panel-default {
+ overflow: visible !important;
+}
+.table-responsive {
+ overflow: visible !important;
+}
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ overflow-x: scroll !important;
+ }
+}
+.footer-add-item {
+ display:block;
+ text-align: center;
+ font-style: italic;
+ padding: 10px;
+ background: #F5F5F5;
+}
+@media (min-width: 992px) {
+ .container {
+ width: 80%;
+ }
+}
+.mass-actions-quarantaine {
+ user-select: none;
+ padding:10px 0 10px 10px;
+}
+.inputMissingAttr {
+ border-color: #FF4136;
+}
\ No newline at end of file
diff --git a/data/web/debug.php b/data/web/debug.php
new file mode 100644
index 00000000..289aa84a
--- /dev/null
+++ b/data/web/debug.php
@@ -0,0 +1,328 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
Rspamd UI
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Rspamd settings map
+
+
+
+
+
+
+
+
+
+
+
Container information
+
+
+
+
+ -
+ =$container;?>
+ setTimestamp(mktime(
+ $StartedAt['hour'],
+ $StartedAt['minute'],
+ $StartedAt['second'],
+ $StartedAt['month'],
+ $StartedAt['day'],
+ $StartedAt['year']));
+ $user_tz = new DateTimeZone(getenv('TZ'));
+ $date->setTimezone($user_tz);
+ $started = $date->format('r');
+ ?>
+ (Started on =$started;?>),
+ Restart
+
+
+
+
+
+
+
+
+
+
+
Postfix
+
+
+
+
+
+
+
+
+
+
+
+
+
Dovecot
+
+
+
+
+
+
+
+
+
+
+
+
+
SOGo
+
+
+
+
+
+
+
+
+
+
+
+
+
Fail2ban
+
+
+
+
+
+
+
+
+
+
+
+
+
Rspamd history
+
+
+
+
+
+
+
+
+
+
+
+
+
Autodiscover
+
+
+
+
+
+
+
+
+
+
+
+
+
Watchdog
+
+
+
+
+
+
+
+
+
+
+
+
+
ACME
+
+
+
+
+
+
+
+
+
+
+
+
+
API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/data/web/img/rspamd_logo.png b/data/web/img/rspamd_logo.png
new file mode 100644
index 00000000..0e97426d
Binary files /dev/null and b/data/web/img/rspamd_logo.png differ
diff --git a/data/web/inc/ajax/container_ctrl.php b/data/web/inc/ajax/container_ctrl.php
new file mode 100644
index 00000000..d12f5767
--- /dev/null
+++ b/data/web/inc/ajax/container_ctrl.php
@@ -0,0 +1,53 @@
+OK' : 'Error: ' . $response['msg'] . '';
+ if ($response['type'] == "success") {
+ break;
+ }
+ usleep(1500000);
+ $retry++;
+ }
+ echo (!isset($last_response)) ? 'Already running' : $last_response;
+ }
+ if ($_GET['action'] == "stop") {
+ header('Content-Type: text/html; charset=utf-8');
+ $retry = 0;
+ while (docker($_GET['service'], 'info')['State']['Running'] == 1 && $retry <= 3) {
+ $response = docker($_GET['service'], 'post', 'stop');
+ $response = json_decode($response, true);
+ $last_response = ($response['type'] == "success") ? 'OK' : 'Error: ' . $response['msg'] . '';
+ if ($response['type'] == "success") {
+ break;
+ }
+ usleep(1500000);
+ $retry++;
+ }
+ echo (!isset($last_response)) ? 'Not running' : $last_response;
+ }
+ if ($_GET['action'] == "restart") {
+ header('Content-Type: text/html; charset=utf-8');
+ $response = docker($_GET['service'], 'post', 'restart');
+ $response = json_decode($response, true);
+ $last_response = ($response['type'] == "success") ? 'OK' : 'Error: ' . $response['msg'] . '';
+ echo (!isset($last_response)) ? 'Cannot restart container' : $last_response;
+ }
+ if ($_GET['action'] == "logs") {
+ $lines = (empty($_GET['lines']) || !is_numeric($_GET['lines'])) ? 1000 : $_GET['lines'];
+ header('Content-Type: text/plain; charset=utf-8');
+ print_r(preg_split('/\n/', docker($_GET['service'], 'logs', $lines)));
+ }
+}
+
+?>
diff --git a/data/web/inc/ajax/log_driver.php b/data/web/inc/ajax/log_driver.php
new file mode 100644
index 00000000..319f672d
--- /dev/null
+++ b/data/web/inc/ajax/log_driver.php
@@ -0,0 +1,12 @@
+
diff --git a/data/web/inc/ajax/qitem_details.php b/data/web/inc/ajax/qitem_details.php
new file mode 100644
index 00000000..a4b80be1
--- /dev/null
+++ b/data/web/inc/ajax/qitem_details.php
@@ -0,0 +1,83 @@
+ 10485760) {
+ echo json_encode(array('error' => 'Message size exceeds 10 MiB.'));
+ exit;
+ }
+ if (!empty($mailc['msg'])) {
+ // Init message array
+ $data = array();
+ // Init parser
+ $mail_parser = new PhpMimeMailParser\Parser();
+ // Load msg to parser
+ $mail_parser->setText($mailc['msg']);
+ // Get text/plain content
+ $data['text_plain'] = $mail_parser->getMessageBody('text');
+ // Get subject
+ $data['subject'] = $mail_parser->getHeader('subject');
+ // Get attachments
+ if (is_dir($tmpdir)) {
+ rrmdir($tmpdir);
+ }
+ mkdir('/tmp/' . $_GET['id']);
+ $mail_parser->saveAttachments($tmpdir, true);
+ $atts = $mail_parser->getAttachments(true);
+ if (count($atts) > 0) {
+ foreach ($atts as $key => $val) {
+ $data['attachments'][$key] = array(
+ // Index
+ // 0 => file name
+ // 1 => mime type
+ // 2 => file size
+ // 3 => vt link by sha256
+ $val->getFilename(),
+ $val->getContentType(),
+ filesize($tmpdir . $val->getFilename()),
+ 'https://www.virustotal.com/file/' . hash_file('SHA256', $tmpdir . $val->getFilename()) . '/analysis/'
+ );
+ }
+ }
+ if (isset($_GET['att'])) {
+ $dl_id = intval($_GET['att']);
+ $dl_filename = $data['attachments'][$dl_id][0];
+ if (!is_dir($tmpdir . $dl_filename) && file_exists($tmpdir . $dl_filename)) {
+ header('Pragma: public');
+ header('Expires: 0');
+ header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+ header('Cache-Control: private', false);
+ header('Content-Type: ' . $data['attachments'][$dl_id][1]);
+ header('Content-Disposition: attachment; filename="'. $dl_filename . '";');
+ header('Content-Transfer-Encoding: binary');
+ header('Content-Length: ' . $data['attachments'][$dl_id][2]);
+ readfile($tmpdir . $dl_filename);
+ exit;
+ }
+ }
+ echo json_encode($data);
+ }
+}
+?>
diff --git a/data/web/inc/ajax/sogo_ctrl.php b/data/web/inc/ajax/sogo_ctrl.php
deleted file mode 100644
index e238d9c0..00000000
--- a/data/web/inc/ajax/sogo_ctrl.php
+++ /dev/null
@@ -1,39 +0,0 @@
-OK' : 'Error: ' . $response['msg'] . '';
- if ($response['type'] == "success") {
- break;
- }
- usleep(1500000);
- $retry++;
- }
- echo (!isset($last_response)) ? 'Already running' : $last_response;
-}
-
-if ($_GET['ACTION'] == "stop") {
- $retry = 0;
- while (docker('sogo-mailcow', 'info')['State']['Running'] == 1 && $retry <= 3) {
- $response = docker('sogo-mailcow', 'post', 'stop');
- $response = json_decode($response, true);
- $last_response = ($response['type'] == "success") ? 'OK' : 'Error: ' . $response['msg'] . '';
- if ($response['type'] == "success") {
- break;
- }
- usleep(1500000);
- $retry++;
- }
- echo (!isset($last_response)) ? 'Not running' : $last_response;
-}
-
-?>
diff --git a/data/web/inc/footer.inc.php b/data/web/inc/footer.inc.php
index 3ba758be..a082211b 100644
--- a/data/web/inc/footer.inc.php
+++ b/data/web/inc/footer.inc.php
@@ -8,6 +8,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/modals/footer.php';
+
@@ -26,11 +27,19 @@ $(document).ready(function() {
msg = $('').html(message).text();
if (type == 'danger') {
auto_hide = 0;
+ $('#' + localStorage.getItem("add_modal")).modal('show');
+ localStorage.removeItem("add_modal");
} else {
auto_hide = 5000;
}
+ $.ajax({
+ url: '/inc/ajax/log_driver.php',
+ data: {"type": type,"msg": msg},
+ type: "GET"
+ });
$.notify({message: msg},{z_index: 20000, delay: auto_hide, type: type,placement: {from: "bottom",align: "right"},animate: {enter: 'animated fadeInUp',exit: 'animated fadeOutDown'}});
}
+ $('[data-cached-form="true"]').formcache({key: $(this).data('id')});
mailcow_alert_box(=json_encode($_SESSION['return']['msg']); ?>, "= $_SESSION['return']['type']; ?>");
@@ -118,13 +127,8 @@ $(document).ready(function() {
}
});
- // Activate tooltips
$(function () {
$('[data-toggle="tooltip"]').tooltip()
- })
- // Hide alerts after n seconds
- $("#alert-fade").fadeTo(7000, 500).slideUp(500, function(){
- $("#alert-fade").alert('close');
});
// Remember last navigation pill
@@ -173,36 +177,32 @@ $(document).ready(function() {
// Init Bootstrap Selectpicker
$('select').selectpicker();
- // Trigger SOGo restart
- $('#triggerRestartSogo').click(function(){
- $(this).prop("disabled",true);
- $(this).html(' ');
- $('#statusTriggerRestartSogo').text('Stopping SOGo workers, this may take a while... ');
- $.ajax({
- method: 'get',
- url: '/inc/ajax/sogo_ctrl.php',
- data: {
- 'ajax': true,
- 'ACTION': 'stop'
- },
- success: function(data) {
- $('#statusTriggerRestartSogo').append(data);
- $('#statusTriggerRestartSogo').append('
Starting SOGo...');
- $.ajax({
- method: 'get',
- url: '/inc/ajax/sogo_ctrl.php',
- data: {
- 'ajax': true,
- 'ACTION': 'start'
- },
- success: function(data) {
- $('#statusTriggerRestartSogo').append(data);
- $('#triggerRestartSogo').html(' ');
- }
- });
- }
+ // Trigger container restart
+ $('#RestartContainer').on('show.bs.modal', function(e) {
+ var container = $(e.relatedTarget).data('container');
+ $('#containerName').text(container);
+ $('#triggerRestartContainer').click(function(){
+ $(this).prop("disabled",true);
+ $(this).html(' ');
+ $('#statusTriggerRestartContainer').text('Restarting container, this may take a while... ');
+ $.ajax({
+ method: 'get',
+ url: '/inc/ajax/container_ctrl.php',
+ timeout: 3000,
+ data: {
+ 'service': container,
+ 'action': 'restart'
+ },
+ error: function() {
+ window.location = window.location.href.split("#")[0];
+ },
+ success: function(data) {
+ $('#statusTriggerRestartContainer').append(data);
+ $('#triggerRestartContainer').html(' ');
+ }
+ });
});
- });
+ })
// CSRF
$('').attr('id', 'csrf_token').attr('name', 'csrf_token').appendTo('form');
@@ -216,4 +216,4 @@ $(document).ready(function() {