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
Various fixes and changes
c9184a9b
data/web/css/admin.css | 6 +-
data/web/css/mailbox.css | 11 +--
data/web/css/mailcow.css | 8 --
data/web/css/user.css | 24 +++++
data/web/inc/functions.inc.php | 212 +++++++++++++++++++----------------------
data/web/inc/header.inc.php | 1 +
data/web/js/admin.js | 2 +-
data/web/js/mailbox.js | 1 -
data/web/js/user.js | 157 +++++++++++++++++++++++++++++-
data/web/json_api.php | 62 +++++++++++-
data/web/mailbox.php | 2 +-
data/web/user.php | 88 +++++------------
12 files changed, 369 insertions(+), 205 deletions(-)
create mode 100644 data/web/css/user.css
Diff
diff --git a/data/web/css/admin.css b/data/web/css/admin.css
index de6fbfa0..a8365f6d 100644
--- a/data/web/css/admin.css
+++ b/data/web/css/admin.css
@@ -18,4 +18,8 @@ body {
body.modal-open {
overflow-y:scroll;
padding-right: inherit !important;
-}
\ No newline at end of file
+}
+.mass-actions-admin {
+ user-select: none;
+ padding:10px 0 10px 0;
+}
diff --git a/data/web/css/mailbox.css b/data/web/css/mailbox.css
index b76f3f29..79e88255 100644
--- a/data/web/css/mailbox.css
+++ b/data/web/css/mailbox.css
@@ -18,15 +18,12 @@ table.footable>tbody>tr.footable-empty>td {
padding: 10px;
background: #F5F5F5;
}
-
-#alias_table {
- cursor:pointer;
-}
-#alias_table .footable-paging {
- cursor: auto;
-}
@media (min-width: 992px) {
.container {
width: 80%;
}
}
+.mass-actions-mailbox {
+ user-select: none;
+ padding:10px 0 10px 10px;
+}
diff --git a/data/web/css/mailcow.css b/data/web/css/mailcow.css
index 3978fcd9..adfc063b 100644
--- a/data/web/css/mailcow.css
+++ b/data/web/css/mailcow.css
@@ -63,11 +63,3 @@ body.modal-open {
max-width: 550px;
z-index: 2000;
}
-.mass-actions-mailbox {
- user-select: none;
- padding:10px 0 10px 10px;
-}
-.mass-actions-admin {
- user-select: none;
- padding:10px 0 10px 0;
-}
diff --git a/data/web/css/user.css b/data/web/css/user.css
new file mode 100644
index 00000000..605a1010
--- /dev/null
+++ b/data/web/css/user.css
@@ -0,0 +1,24 @@
+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;
+}
+.footer-add-item {
+ display:block;
+ text-align: center;
+ font-style: italic;
+ padding: 10px;
+ background: #F5F5F5;
+}
+.mass-actions-user {
+ user-select: none;
+ padding:10px 0 10px 0;
+}
diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php
index a1a6d935..40e6a86a 100644
--- a/data/web/inc/functions.inc.php
+++ b/data/web/inc/functions.inc.php
@@ -867,7 +867,7 @@ function delete_policy_list_item($postarray) {
return true;
}
function get_syncjobs($username = null) {
- // 'username' can be be set, if not, default to mailcow_cc_username
+ // 'username' can be set, if not set, defaults to mailcow_cc_username
global $lang;
global $pdo;
$data = array();
@@ -880,7 +880,10 @@ function get_syncjobs($username = null) {
$username = $_SESSION['mailcow_cc_username'];
}
try {
- $stmt = $pdo->prepare("SELECT *, CONCAT(LEFT(`password1`, 3), '…') as `password1_short`
+ $stmt = $pdo->prepare("SELECT *,
+ CONCAT(LEFT(`password1`, 3), '...') AS `password1_short`,
+ `active` AS `active_int`,
+ CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
FROM `imapsync`
WHERE `user2` = :username");
$stmt->execute(array(':username' => $username));
@@ -1096,126 +1099,107 @@ function add_syncjob($postarray) {
}
function edit_syncjob($postarray) {
// Array items
- // 'username' can be set, defaults to mailcow_cc_username
global $lang;
global $pdo;
- if (isset($postarray['username']) && filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $postarray['username'])) {
+ if (!is_array($postarray['id'])) {
+ $ids = array();
+ $ids[] = $postarray['id'];
+ }
+ else {
+ $ids = $postarray['id'];
+ }
+
+ foreach ($ids as $id) {
+ $is_now = get_syncjob_details($id);
+ if (!empty($is_now)) {
+ $username = $is_now['user2'];
+ $user1 = (!empty($postarray['user1'])) ? $postarray['user1'] : $is_now['user1'];
+ $active = (isset($postarray['active'])) ? $postarray['active'] : $is_now['active_int'];
+ $delete2duplicates = (isset($postarray['delete2duplicates'])) ? $postarray['delete2duplicates'] : $is_now['delete2duplicates'];
+ $delete1 = (isset($postarray['delete1'])) ? $postarray['delete1'] : $is_now['delete1'];
+ $port1 = (!empty($postarray['port1'])) ? $postarray['port1'] : $is_now['port1'];
+ $password1 = (!empty($postarray['password1'])) ? $postarray['password1'] : $is_now['password1'];
+ $host1 = (!empty($postarray['host1'])) ? $postarray['host1'] : $is_now['host1'];
+ $subfolder2 = (!empty($postarray['subfolder2'])) ? $postarray['subfolder2'] : $is_now['subfolder2'];
+ $enc1 = (!empty($postarray['enc1'])) ? $postarray['enc1'] : $is_now['enc1'];
+ $mins_interval = (!empty($postarray['mins_interval'])) ? $postarray['mins_interval'] : $is_now['mins_interval'];
+ $exclude = (!empty($postarray['exclude'])) ? $postarray['exclude'] : $is_now['exclude'];
+ $maxage = (!empty($postarray['maxage'])) ? $postarray['maxage'] : $is_now['maxage'];
+ }
+ else {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
- else {
- $username = $postarray['username'];
+ if (empty($subfolder2)) {
+ $subfolder2 = "";
+ }
+ if (!isset($maxage) || !filter_var($maxage, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 32767)))) {
+ $maxage = "0";
+ }
+ if (!filter_var($port1, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 65535)))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (!filter_var($mins_interval, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 3600)))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (!is_valid_domain_name($host1)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if ($enc1 != "TLS" && $enc1 != "SSL" && $enc1 != "PLAIN") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (@preg_match("/" . $exclude . "/", null) === false) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("UPDATE `imapsync` SET `delete1` = :delete1, `maxage` = :maxage, `subfolder2` = :subfolder2, `exclude` = :exclude, `host1` = :host1, `user1` = :user1, `password1` = :password1, `mins_interval` = :mins_interval, `port1` = :port1, `enc1` = :enc1, `delete2duplicates` = :delete2duplicates, `active` = :active
+ WHERE `id` = :id");
+ $stmt->execute(array(
+ ':delete1' => $delete1,
+ ':id' => $id,
+ ':exclude' => $exclude,
+ ':maxage' => $maxage,
+ ':subfolder2' => $subfolder2,
+ ':host1' => $host1,
+ ':user1' => $user1,
+ ':password1' => $password1,
+ ':mins_interval' => $mins_interval,
+ ':port1' => $port1,
+ ':enc1' => $enc1,
+ ':delete2duplicates' => $delete2duplicates,
+ ':active' => $active,
+ ));
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
}
- }
- else {
- $username = $_SESSION['mailcow_cc_username'];
- }
-
- $active = intval($postarray['active']);
- $delete2duplicates = intval($postarray['delete2duplicates']);
- $delete1 = intval($postarray['delete1']);
- $id = $postarray['id'];
- $port1 = $postarray['port1'];
- $host1 = $postarray['host1'];
- $password1 = $postarray['password1'];
- $exclude = $postarray['exclude'];
- $maxage = $postarray['maxage'];
- $subfolder2 = $postarray['subfolder2'];
- $user1 = $postarray['user1'];
- $mins_interval = $postarray['mins_interval'];
- $enc1 = $postarray['enc1'];
-
- if (empty($subfolder2)) {
- $subfolder2 = "";
- }
- if (!isset($maxage) || !filter_var($maxage, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 32767)))) {
- $maxage = "0";
- }
- if (!filter_var($port1, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 65535)))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (!filter_var($mins_interval, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 3600)))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (!is_valid_domain_name($host1)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if ($enc1 != "TLS" && $enc1 != "SSL" && $enc1 != "PLAIN") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (@preg_match("/" . $exclude . "/", null) === false) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("SELECT `user2` FROM `imapsync`
- WHERE `user2` = :user2 AND `id` = :id");
- $stmt->execute(array(':user2' => $username, ':id' => $id));
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- if (empty($num_results)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("UPDATE `imapsync` set `delete1` = :delete1, `maxage` = :maxage, `subfolder2` = :subfolder2, `exclude` = :exclude, `host1` = :host1, `user1` = :user1, `password1` = :password1, `mins_interval` = :mins_interval, `port1` = :port1, `enc1` = :enc1, `delete2duplicates` = :delete2duplicates, `active` = :active
- WHERE `user2` = :user2 AND `id` = :id");
- $stmt->execute(array(
- ':user2' => $username,
- ':delete1' => $delete1,
- ':id' => $id,
- ':exclude' => $exclude,
- ':maxage' => $maxage,
- ':subfolder2' => $subfolder2,
- ':host1' => $host1,
- ':user1' => $user1,
- ':password1' => $password1,
- ':mins_interval' => $mins_interval,
- ':port1' => $port1,
- ':enc1' => $enc1,
- ':delete2duplicates' => $delete2duplicates,
- ':active' => $active,
- ));
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
}
$_SESSION['return'] = array(
'type' => 'success',
@@ -2479,7 +2463,7 @@ function dkim_delete_key($postarray) {
$selector = $redis->hGet('DKIM_SELECTORS', $domain);
$redis->hDel('DKIM_PUB_KEYS', $domain);
$redis->hDel('DKIM_PRIV_KEYS', $selector . '.' . $domain);
- $redis->hDel('DKIM_SELECTORS', $selector);
+ $redis->hDel('DKIM_SELECTORS', $domain);
}
catch (RedisException $e) {
$_SESSION['return'] = array(
diff --git a/data/web/inc/header.inc.php b/data/web/inc/header.inc.php
index e9240376..170335e3 100644
--- a/data/web/inc/header.inc.php
+++ b/data/web/inc/header.inc.php
@@ -21,6 +21,7 @@
<link rel="stylesheet" href="/css/animate.min.css">
<?= (preg_match("/mailbox.php/i", $_SERVER['REQUEST_URI'])) ? '<link rel="stylesheet" href="/css/mailbox.css">' : null; ?>
<?= (preg_match("/admin.php/i", $_SERVER['REQUEST_URI'])) ? '<link rel="stylesheet" href="/css/admin.css">' : null; ?>
+<?= (preg_match("/user.php/i", $_SERVER['REQUEST_URI'])) ? '<link rel="stylesheet" href="/css/user.css">' : null; ?>
<link rel="shortcut icon" href="/favicon.png" type="image/png">
<link rel="icon" href="/favicon.png" type="image/png">
</head>
diff --git a/data/web/js/admin.js b/data/web/js/admin.js
index 711070dd..9d6642b9 100644
--- a/data/web/js/admin.js
+++ b/data/web/js/admin.js
@@ -56,7 +56,7 @@ $(document).ready(function() {
url: '/api/v1/' + api_url,
jsonp: false,
complete: function (data) {
- location.assign(window.location);
+ location.reload(true);
}
});
})
diff --git a/data/web/js/mailbox.js b/data/web/js/mailbox.js
index 0ec0d5e2..100c9235 100644
--- a/data/web/js/mailbox.js
+++ b/data/web/js/mailbox.js
@@ -88,7 +88,6 @@ $(document).ready(function() {
$('#ConfirmDeleteModal').modal('hide');
});;
});
-
});
jQuery(function($){
diff --git a/data/web/js/user.js b/data/web/js/user.js
index 8d9450be..7959cc5a 100644
--- a/data/web/js/user.js
+++ b/data/web/js/user.js
@@ -22,12 +22,165 @@ $(document).ready(function() {
// Init Bootstrap Switch
$.fn.bootstrapSwitch.defaults.onColor = 'success';
- $("[name='tls_out']").bootstrapSwitch();
- $("[name='tls_in']").bootstrapSwitch();
+ $("#tls_out").bootstrapSwitch();
+ $("#tls_in").bootstrapSwitch();
// Log modal
$('#logModal').on('show.bs.modal', function(e) {
var logText = $(e.relatedTarget).data('log-text');
$(e.currentTarget).find('#logText').html('<pre style="background:none;font-size:11px;line-height:1.1;border:0px">' + logText + '</pre>');
});
+
+ // Collect values of input fields with name multi_select with same data-id to js array multi_data[data-id]
+ var multi_data = [];
+ $(document).on('change', 'input[name=multi_select]:checkbox', function() {
+ if ($(this).is(':checked') && $(this).data('id')) {
+ var id = $(this).data('id');
+ if (typeof multi_data[id] == "undefined") {
+ multi_data[id] = [];
+ }
+ multi_data[id].push($(this).val());
+ }
+ else {
+ var id = $(this).data('id');
+ multi_data[id].splice($.inArray($(this).val(), multi_data[id]),1);
+ }
+ });
+ // Select checkbox by click on parent tr
+ $(document).on('click', 'tbody>tr', function(e) {
+ if (e.target.type == "checkbox") {
+ e.stopPropagation();
+ } else {
+ var checkbox = $(this).find(':checkbox');
+ checkbox.trigger('click');
+ }
+ });
+ // Select or deselect all checkboxes with same data-id
+ $(document).on('click', '#toggle_multi_select_all', function(e) {
+ e.preventDefault();
+ id = $(this).data("id");
+ multi_data[id] = [];
+ var all_checkboxes = $("input[data-id=" + id + "]:enabled");
+ all_checkboxes.prop("checked", !all_checkboxes.prop("checked")).change();
+ });
+ // General API edit actions
+ $(document).on('click', '#edit_selected', function(e) {
+ e.preventDefault();
+ var id = $(this).data('id');
+ if (typeof multi_data[id] == "undefined") return;
+ data_array = multi_data[id];
+ api_url = $(this).data('api-url');
+ api_attr = $(this).data('api-attr');
+ if (Object.keys(data_array).length !== 0) {
+ $.ajax({
+ type: "POST",
+ dataType: "json",
+ data: { "items": JSON.stringify(data_array), "attr": JSON.stringify(api_attr), "csrf_token": csrf_token },
+ url: '/api/v1/' + api_url,
+ jsonp: false,
+ complete: function (data) {
+ // var reponse = (JSON.parse(data.responseText));
+ // console.log(reponse.type);
+ // console.log(reponse.msg);
+ location.assign(window.location);
+ }
+ });
+ }
+ });
+ // General API delete actions
+ $(document).on('click', '#delete_selected', function(e) {
+ e.preventDefault();
+ var id = $(this).data('id');
+ if (typeof multi_data[id] == "undefined" || multi_data[id] == "") return;
+ data_array = multi_data[id];
+ api_url = $(this).data('api-url');
+ $(document).on('show.bs.modal','#ConfirmDeleteModal', function () {
+ $("#ItemsToDelete").empty();
+ for (var i in data_array) {
+ $("#ItemsToDelete").append("<li>" + data_array[i] + "</li>");
+ }
+ })
+ $('#ConfirmDeleteModal').modal({
+ backdrop: 'static',
+ keyboard: false
+ })
+ .one('click', '#IsConfirmed', function(e) {
+ $.ajax({
+ type: "POST",
+ dataType: "json",
+ data: { "items": JSON.stringify(data_array), "csrf_token": csrf_token },
+ url: '/api/v1/' + api_url,
+ jsonp: false,
+ complete: function (data) {
+ location.reload(true);
+ }
+ });
+ })
+ .one('click', '#isCanceled', function(e) {
+ $('#ConfirmDeleteModal').modal('hide');
+ });;
+ });
+});
+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];
+ });
+ }
+ function draw_sync_job_table() {
+ ft_aliasdomain_table = FooTable.init('#sync_job_table', {
+ "columns": [
+ {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
+ {"sorted": true,"name":"server_w_port","title":"Server"},
+ {"name":"enc1","title":lang.encryption},
+ {"name":"user1","title":lang.username},
+ {"name":"exclude","title":lang.excludes},
+ {"name":"mins_interval","title":lang.interval + " (min)"},
+ {"name":"last_run","title":lang.last_run},
+ {"name":"log","title":"Log"},
+ {"name":"active","filterable": false,"style":{"maxWidth":"50px","width":"70px"},"title":lang.active},
+ {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
+ ],
+ "empty": lang.empty,
+ "rows": $.ajax({
+ dataType: 'json',
+ url: '/api/v1/get/syncjob',
+ jsonp: false,
+ error: function () {
+ console.log('Cannot draw sync job table');
+ },
+ success: function (data) {
+ $.each(data, function (i, item) {
+ item.log = '<a href="#logModal" data-toggle="modal" data-log-text="' + escapeHtml(item.returned_text) + '">Open logs</a>'
+ item.exclude = '<code>' + item.exclude + '</code>'
+ item.server_w_port = item.host1 + ':' + item.port1;
+ item.action = '<div class="btn-group">' +
+ '<a href="/edit.php?syncjob=' + item.id + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
+ '</div>';
+ item.chkbox = '<input type="checkbox" data-id="syncjob" name="multi_select" value="' + item.id + '" />';
+ });
+ }
+ }),
+ "paging": {
+ "enabled": true,
+ "limit": 5,
+ "size": pagination_size
+ },
+ "sorting": {
+ "enabled": true
+ }
+ });
+ }
+ draw_sync_job_table();
});
\ No newline at end of file
diff --git a/data/web/json_api.php b/data/web/json_api.php
index 0301659a..a2d08e39 100644
--- a/data/web/json_api.php
+++ b/data/web/json_api.php
@@ -151,7 +151,19 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
break;
-
+ }
+ break;
+ case "syncjob":
+ switch ($object) {
+ default:
+ $data = get_syncjobs($object);
+ if (!isset($data) || empty($data)) {
+ echo '{}';
+ }
+ else {
+ echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
+ }
+ break;
}
break;
case "resource":
@@ -183,7 +195,6 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
echo '{}';
}
break;
-
default:
$data = mailbox_get_resource_details($object);
if (!isset($data) || empty($data)) {
@@ -193,7 +204,6 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
break;
-
}
break;
case "fwdhost":
@@ -226,7 +236,6 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
break;
-
}
break;
case "alias-domain":
@@ -258,7 +267,6 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
echo '{}';
}
break;
-
default:
$data = mailbox_get_alias_domains($object);
if (!isset($data) || empty($data)) {
@@ -756,6 +764,50 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
));
}
break;
+ case "syncjob":
+ if (isset($_POST['items']) && isset($_POST['attr'])) {
+ $items = (array)json_decode($_POST['items'], true);
+ $attr = (array)json_decode($_POST['attr'], true);
+ $postarray = array_merge(array('id' => $items), $attr);
+ if (is_array($postarray['id'])) {
+ if (edit_syncjob($postarray) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Edit failed'
+ ));
+ }
+ exit();
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ break;
case "resource":
if (isset($_POST['items']) && isset($_POST['attr'])) {
$items = (array)json_decode($_POST['items'], true);
diff --git a/data/web/mailbox.php b/data/web/mailbox.php
index b04ae968..b10bb414 100644
--- a/data/web/mailbox.php
+++ b/data/web/mailbox.php
@@ -152,7 +152,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
<a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="alias" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
<a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['quick_actions'];?> <span class="caret"></span></a>
<ul class="dropdown-menu">
- <li><a id="edit_selected" data-id="alias" data-api-url='edit/alias' data-api-attr='{"active":"1","active1":"12"}' href="#"><?=$lang['mailbox']['activate'];?></a></li>
+ <li><a id="edit_selected" data-id="alias" data-api-url='edit/alias' data-api-attr='{"active":"1"}' href="#"><?=$lang['mailbox']['activate'];?></a></li>
<li><a id="edit_selected" data-id="alias" data-api-url='edit/alias' data-api-attr='{"active":"0"}' href="#"><?=$lang['mailbox']['deactivate'];?></a></li>
<li role="separator" class="divider"></li>
<li><a id="delete_selected" data-id="alias" data-api-url='delete/alias' href="#"><?=$lang['mailbox']['remove'];?></a></li>
diff --git a/data/web/user.php b/data/web/user.php
index d5c75abc..7a3d6f87 100644
--- a/data/web/user.php
+++ b/data/web/user.php
@@ -408,71 +408,21 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
</div>
<div role="tabpanel" class="tab-pane" id="Syncjobs">
<div class="table-responsive">
- <table class="table table-striped" id="timelimitedaliases">
- <thead>
- <tr>
- <th class="sort-table" style="min-width: 96px;">Server:Port</th>
- <th class="sort-table" style="min-width: 96px;"><?=$lang['user']['encryption'];?></th>
- <th class="sort-table" style="min-width: 96px;"><?=$lang['user']['username'];?></th>
- <th class="sort-table" style="min-width: 96px;"><?=$lang['user']['excludes'];?></th>
- <th class="sort-table" style="min-width: 35px;"><?=$lang['user']['interval'];?></th>
- <th class="sort-table" style="min-width: 35px;"><?=$lang['user']['last_run'];?></th>
- <th class="sort-table" style="min-width: 35px;">Log</th>
- <th class="sort-table" style="max-width: 95px;"><?=$lang['user']['active'];?></th>
- <th style="text-align: right; min-width: 200px;"><?=$lang['user']['action'];?></th>
- </tr>
- </thead>
- <tbody>
- <?php
- $get_syncjobs = get_syncjobs($username);
- if (!empty($get_syncjobs)):
- foreach ($get_syncjobs as $row):
- ?>
- <tr id="data">
- <td><?=htmlspecialchars($row['host1'] . ':' . $row['port1']);?></td>
- <td><?=htmlspecialchars($row['enc1']);?></td>
- <td><?=htmlspecialchars($row['user1']);?></td>
- <td><?=($row['exclude'] == '') ? '✘' : '<code>' . $row['exclude'] . '</code>';?></td>
- <td><?=htmlspecialchars($row['mins_interval']);?> min</td>
- <td><?=(empty($row['last_run'])) ? '✘' : htmlspecialchars(date($lang['user']['syncjob_full_date'], strtotime($row['last_run'])));?></td>
- <td>
- <?php
- if (empty($row['returned_text'])) {
- echo '✘';
- }
- else {
- ?>
- <a href="#logModal" data-toggle="modal" data-log-text="<?=htmlspecialchars($row['returned_text']);?>">Open logs</a>
- <?php
- }
- ?>
- </td>
- <td><?=($row['active'] == '1') ? '✔' : '✘';?></td>
- <td style="text-align: right;">
- <div class="btn-group">
- <a href="/edit.php?syncjob=<?=urlencode($row['id']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['user']['edit'];?></a>
- <a href="/delete.php?syncjob=<?=urlencode($row['id']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['user']['remove'];?></a>
- </div>
- </td>
- </tr>
- <?php
- endforeach;
- else:
- ?>
- <tr id="no-data"><td colspan="9" style="text-align: center; font-style: italic;"><?=$lang['user']['no_record'];?></td></tr>
- <?php
- endif;
- ?>
- </tbody>
- <tfoot>
- <tr id="no-data">
- <td colspan="9" style="text-align: center; font-style: normal; border-top: 1px solid #e7e7e7;">
- <a href="/add.php?syncjob"><?=$lang['user']['create_syncjob'];?></a>
- </td>
- </tr>
- </tfoot>
- </table>
+ <table class="table table-striped" id="sync_job_table"></table>
</div>
+ <div class="mass-actions-user">
+ <div class="btn-group">
+ <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="syncjob" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+ <a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['quick_actions'];?> <span class="caret"></span></a>
+ <ul class="dropdown-menu">
+ <li><a id="edit_selected" data-id="syncjob" data-api-url='edit/syncjob' data-api-attr='{"active":"1"}' href="#"><?=$lang['mailbox']['activate'];?></a></li>
+ <li><a id="edit_selected" data-id="syncjob" data-api-url='edit/syncjob' data-api-attr='{"active":"0"}' href="#"><?=$lang['mailbox']['deactivate'];?></a></li>
+ <li role="separator" class="divider"></li>
+ <li><a id="delete_selected" data-id="syncjob" data-api-url='delete/syncjob' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+ </ul>
+ <a class="btn btn-sm btn-success" href="/add.php?syncjob"><?=$lang['user']['create_syncjob'];?></a>
+ </div>
+ </div>
</div>
</div>
</div>
@@ -533,7 +483,15 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "use
</div>
</div>
</div> <!-- /container -->
-<script src="js/sorttable.js"></script>
+<script type='text/javascript'>
+<?php
+$lang_user = json_encode($lang['user']);
+echo "var lang = ". $lang_user . ";\n";
+echo "var csrf_token = '". $_SESSION['CSRF']['TOKEN'] . "';\n";
+echo "var pagination_size = '". $PAGINATION_SIZE . "';\n";
+?>
+</script>
+<script src="js/footable.min.js"></script>
<script src="js/user.js"></script>
<?php
require_once("inc/footer.inc.php");