Browse Source

Various fixes and changes

andryyy 8 years ago
parent
commit
c9184a9bad

+ 5 - 1
data/web/css/admin.css

@@ -18,4 +18,8 @@ body {
 body.modal-open {
 body.modal-open {
   overflow-y:scroll;
   overflow-y:scroll;
   padding-right: inherit !important;
   padding-right: inherit !important;
-}
+}
+.mass-actions-admin {
+  user-select: none;
+  padding:10px 0 10px 0;
+}

+ 4 - 7
data/web/css/mailbox.css

@@ -18,15 +18,12 @@ table.footable>tbody>tr.footable-empty>td {
   padding: 10px;
   padding: 10px;
   background: #F5F5F5;
   background: #F5F5F5;
 }
 }
-
-#alias_table {
-  cursor:pointer;
-}
-#alias_table .footable-paging {
-  cursor:	auto;
-}
 @media (min-width: 992px) {
 @media (min-width: 992px) {
   .container {
   .container {
       width: 80%;
       width: 80%;
   }
   }
 }
 }
+.mass-actions-mailbox {
+  user-select: none;
+  padding:10px 0 10px 10px;
+}

+ 0 - 8
data/web/css/mailcow.css

@@ -63,11 +63,3 @@ body.modal-open {
   max-width: 550px;
   max-width: 550px;
   z-index: 2000;
   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;
-}

+ 24 - 0
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;
+}

+ 98 - 114
data/web/inc/functions.inc.php

@@ -867,7 +867,7 @@ function delete_policy_list_item($postarray) {
   return true;
   return true;
 }
 }
 function get_syncjobs($username = null) {
 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 $lang;
 	global $pdo;
 	global $pdo;
   $data = array();
   $data = array();
@@ -880,7 +880,10 @@ function get_syncjobs($username = null) {
     $username = $_SESSION['mailcow_cc_username'];
     $username = $_SESSION['mailcow_cc_username'];
   }
   }
   try {
   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`
         FROM `imapsync`
           WHERE `user2` = :username");
           WHERE `user2` = :username");
     $stmt->execute(array(':username' => $username));
     $stmt->execute(array(':username' => $username));
@@ -1096,126 +1099,107 @@ function add_syncjob($postarray) {
 }
 }
 function edit_syncjob($postarray) {
 function edit_syncjob($postarray) {
   // Array items
   // Array items
-  // 'username' can be set, defaults to mailcow_cc_username
 	global $lang;
 	global $lang;
 	global $pdo;
 	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(
       $_SESSION['return'] = array(
         'type' => 'danger',
         'type' => 'danger',
         'msg' => sprintf($lang['danger']['access_denied'])
         'msg' => sprintf($lang['danger']['access_denied'])
       );
       );
       return false;
       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(
   $_SESSION['return'] = array(
     'type' => 'success',
     'type' => 'success',
@@ -2479,7 +2463,7 @@ function dkim_delete_key($postarray) {
       $selector = $redis->hGet('DKIM_SELECTORS', $domain);
       $selector = $redis->hGet('DKIM_SELECTORS', $domain);
       $redis->hDel('DKIM_PUB_KEYS', $domain);
       $redis->hDel('DKIM_PUB_KEYS', $domain);
       $redis->hDel('DKIM_PRIV_KEYS', $selector . '.' . $domain);
       $redis->hDel('DKIM_PRIV_KEYS', $selector . '.' . $domain);
-      $redis->hDel('DKIM_SELECTORS', $selector);
+      $redis->hDel('DKIM_SELECTORS', $domain);
     }
     }
     catch (RedisException $e) {
     catch (RedisException $e) {
       $_SESSION['return'] = array(
       $_SESSION['return'] = array(

+ 1 - 0
data/web/inc/header.inc.php

@@ -21,6 +21,7 @@
 <link rel="stylesheet" href="/css/animate.min.css">
 <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("/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("/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="shortcut icon" href="/favicon.png" type="image/png">
 <link rel="icon" href="/favicon.png" type="image/png">
 <link rel="icon" href="/favicon.png" type="image/png">
 </head>
 </head>

+ 1 - 1
data/web/js/admin.js

@@ -56,7 +56,7 @@ $(document).ready(function() {
           url: '/api/v1/' + api_url,
           url: '/api/v1/' + api_url,
           jsonp: false,
           jsonp: false,
           complete: function (data) {
           complete: function (data) {
-            location.assign(window.location);
+            location.reload(true);
           }
           }
         });
         });
       })
       })

+ 0 - 1
data/web/js/mailbox.js

@@ -88,7 +88,6 @@ $(document).ready(function() {
         $('#ConfirmDeleteModal').modal('hide');
         $('#ConfirmDeleteModal').modal('hide');
       });;
       });;
   });
   });
-
 });
 });
 
 
 jQuery(function($){
 jQuery(function($){

+ 155 - 2
data/web/js/user.js

@@ -22,12 +22,165 @@ $(document).ready(function() {
 
 
 	// Init Bootstrap Switch
 	// Init Bootstrap Switch
 	$.fn.bootstrapSwitch.defaults.onColor = 'success';
 	$.fn.bootstrapSwitch.defaults.onColor = 'success';
-	$("[name='tls_out']").bootstrapSwitch();
-	$("[name='tls_in']").bootstrapSwitch();
+	$("#tls_out").bootstrapSwitch();
+	$("#tls_in").bootstrapSwitch();
 
 
   // Log modal
   // Log modal
   $('#logModal').on('show.bs.modal', function(e) {
   $('#logModal').on('show.bs.modal', function(e) {
   var logText = $(e.relatedTarget).data('log-text');
   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>');
   $(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 = {
+  '&': '&amp;',
+  '<': '&lt;',
+  '>': '&gt;',
+  '"': '&quot;',
+  "'": '&#39;',
+  '/': '&#x2F;',
+  '`': '&#x60;',
+  '=': '&#x3D;'
+  };
+  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();
 });
 });

+ 57 - 5
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);
                   echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
                 }
                 }
               break;
               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;
           break;
           case "resource":
           case "resource":
@@ -183,7 +195,6 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
                   echo '{}';
                   echo '{}';
                 }
                 }
               break;
               break;
-
               default:
               default:
                 $data = mailbox_get_resource_details($object);
                 $data = mailbox_get_resource_details($object);
                 if (!isset($data) || empty($data)) {
                 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);
                   echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
                 }
                 }
               break;
               break;
-
             }
             }
           break;
           break;
           case "fwdhost":
           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);
                   echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
                 }
                 }
               break;
               break;
-
             }
             }
           break;
           break;
           case "alias-domain":
           case "alias-domain":
@@ -258,7 +267,6 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
                   echo '{}';
                   echo '{}';
                 }
                 }
               break;
               break;
-
               default:
               default:
                 $data = mailbox_get_alias_domains($object);
                 $data = mailbox_get_alias_domains($object);
                 if (!isset($data) || empty($data)) {
                 if (!isset($data) || empty($data)) {
@@ -756,6 +764,50 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
               ));
               ));
             }
             }
           break;
           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":
           case "resource":
             if (isset($_POST['items']) && isset($_POST['attr'])) {
             if (isset($_POST['items']) && isset($_POST['attr'])) {
               $items = (array)json_decode($_POST['items'], true);
               $items = (array)json_decode($_POST['items'], true);

+ 1 - 1
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" 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>
                 <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">
                 <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><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 role="separator" class="divider"></li>
                   <li><a id="delete_selected" data-id="alias" data-api-url='delete/alias' href="#"><?=$lang['mailbox']['remove'];?></a></li>
                   <li><a id="delete_selected" data-id="alias" data-api-url='delete/alias' href="#"><?=$lang['mailbox']['remove'];?></a></li>

+ 23 - 65
data/web/user.php

@@ -408,71 +408,21 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
 	</div>
 	</div>
 	<div role="tabpanel" class="tab-pane" id="Syncjobs">
 	<div role="tabpanel" class="tab-pane" id="Syncjobs">
 		<div class="table-responsive">
 		<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'] == '') ? '&#10008;' : '<code>' . $row['exclude'] . '</code>';?></td>
-				<td><?=htmlspecialchars($row['mins_interval']);?> min</td>
-				<td><?=(empty($row['last_run'])) ? '&#10008;' : htmlspecialchars(date($lang['user']['syncjob_full_date'], strtotime($row['last_run'])));?></td>
-				<td>
-        <?php
-        if (empty($row['returned_text'])) {
-          echo '&#10008;';
-        }
-        else {
-        ?>
-          <a href="#logModal" data-toggle="modal" data-log-text="<?=htmlspecialchars($row['returned_text']);?>">Open logs</a>
-        <?php
-        }
-        ?>
-        </td>
-				<td><?=($row['active'] == '1') ? '&#10004;' : '&#10008;';?></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>
+    <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>
 	</div>
 </div>
 </div>
@@ -533,7 +483,15 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "use
   </div>
   </div>
 </div>
 </div>
 </div> <!-- /container -->
 </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>
 <script src="js/user.js"></script>
 <?php
 <?php
 require_once("inc/footer.inc.php");
 require_once("inc/footer.inc.php");