ソースを参照

[Web] Sync jobs can be created/viewed/edited by admins/domain admins; Various fixes or improvements

andryyy 8 年 前
コミット
66e06a0c0c

+ 1 - 1
data/web/admin.php

@@ -122,7 +122,7 @@ $tfa_data = get_tfa();
 
 
   <div role="tabpanel" class="tab-pane" id="tab-config">
   <div role="tabpanel" class="tab-pane" id="tab-config">
     <div class="row">
     <div class="row">
-    <div class="col-sm-2 hidden-xs">
+    <div id="sidebar-admin" class="col-sm-2 hidden-xs">
       <div id="scrollbox" class="list-group">
       <div id="scrollbox" class="list-group">
         <a href="#dkim" class="list-group-item"><?=$lang['admin']['dkim_keys'];?></a>
         <a href="#dkim" class="list-group-item"><?=$lang['admin']['dkim_keys'];?></a>
         <a href="#fwdhosts" class="list-group-item"><?=$lang['admin']['forwarding_hosts'];?></a>
         <a href="#fwdhosts" class="list-group-item"><?=$lang['admin']['forwarding_hosts'];?></a>

+ 637 - 645
data/web/edit.php

@@ -16,690 +16,682 @@ require_once("inc/header.inc.php");
 				</div>
 				</div>
 				<div class="panel-body">
 				<div class="panel-body">
 <?php
 <?php
-if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "admin"  || $_SESSION['mailcow_cc_role'] == "domainadmin")) {
-		if (isset($_GET["alias"]) &&
-			!empty($_GET["alias"])) {
-				$alias = $_GET["alias"];
-        $result = mailbox('get', 'alias_details', $alias);
-				if (!empty($result)) {
-				?>
-					<h4><?=$lang['edit']['alias'];?></h4>
-					<br />
-					<form class="form-horizontal" data-id="editalias" role="form" method="post">
-						<input type="hidden" value="0" name="active">
-						<div class="form-group">
-							<label class="control-label col-sm-2" for="goto"><?=$lang['edit']['target_address'];?></label>
-							<div class="col-sm-10">
-								<textarea class="form-control" autocapitalize="none" autocorrect="off" rows="10" id="goto" name="goto"><?=htmlspecialchars($result['goto']) ?></textarea>
-							</div>
-						</div>
-						<div class="form-group">
-							<div class="col-sm-offset-2 col-sm-10">
-								<div class="checkbox">
-								<label><input type="checkbox" value="1" name="active" <?php if (isset($result['active_int']) && $result['active_int']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
-								</div>
-							</div>
-						</div>
-						<div class="form-group">
-							<div class="col-sm-offset-2 col-sm-10">
-                <button class="btn btn-success" id="edit_selected" data-id="editalias" data-item="<?=$alias;?>" data-api-url='edit/alias' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
-							</div>
-						</div>
-					</form>
-				<?php
-				}
-				else {
-				?>
-					<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
-				<?php
-				}
-		}
-		elseif (isset($_GET['domainadmin']) &&
-				ctype_alnum(str_replace(array('_', '.', '-'), '', $_GET["domainadmin"])) &&
-				!empty($_GET["domainadmin"]) &&
-				$_GET["domainadmin"] != 'admin' &&
-				$_SESSION['mailcow_cc_role'] == "admin") {
-				$domain_admin = $_GET["domainadmin"];
-				$result = domain_admin('details', $domain_admin);
-				if (!empty($result)) {
-				?>
-				<h4><?=$lang['edit']['domain_admin'];?></h4>
-				<br />
-				<form class="form-horizontal" data-id="editdomainadmin" role="form" method="post">
-					<input type="hidden" value="0" name="active">
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="username_new"><?=$lang['edit']['username'];?></label>
-						<div class="col-sm-10">
-              <input class="form-control" type="text" name="username_new" value="<?=htmlspecialchars($domain_admin);?>" />
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="domains"><?=$lang['edit']['domains'];?></label>
-						<div class="col-sm-10">
-							<select id="domains" name="domains[]" multiple required>
-							<?php
-							foreach ($result['selected_domains'] as $domain):
-							?>
-								<option selected><?=htmlspecialchars($domain);?></option>
-							<?php
-							endforeach;
-							foreach ($result['unselected_domains'] as $domain):
-							?>
-								<option><?=htmlspecialchars($domain);?></option>
-							<?php
-							endforeach;
-							?>
-							</select>
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="password"><?=$lang['edit']['password'];?></label>
-						<div class="col-sm-10">
-						<input type="password" class="form-control" name="password" id="password" placeholder="">
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="password2"><?=$lang['edit']['password_repeat'];?></label>
-						<div class="col-sm-10">
-						<input type="password" class="form-control" name="password2" id="password2">
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-							<div class="checkbox">
-							<label><input type="checkbox" value="1" name="active" <?php if (isset($result['active_int']) && $result['active_int']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
-							</div>
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-							<div class="checkbox">
-							<label><input type="checkbox" value="1" name="disable_tfa"> <?=$lang['tfa']['disable_tfa'];?></label>
-							</div>
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-              <button class="btn btn-success" id="edit_selected" data-id="editdomainadmin" data-item="<?=$domain_admin;?>" data-api-url='edit/domain-admin' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
-						</div>
-					</div>
-				</form>
-			<?php
-			}
-			else {
-			?>
-				<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
-			<?php
-			}
-	}
-	elseif (isset($_GET['domain']) &&
-		is_valid_domain_name($_GET["domain"]) &&
-		!empty($_GET["domain"])) {
-			$domain = $_GET["domain"];
-      $result = mailbox('get', 'domain_details', $domain);
-      $rl = mailbox('get', 'domain_ratelimit', $domain);
-      $rlyhosts = relayhost('get');
-			if (!empty($result)) {
-			?>
-				<h4><?=$lang['edit']['domain'];?></h4>
-				<form data-id="editdomain" class="form-horizontal" role="form" method="post">
-					<input type="hidden" value="0" name="active">
-					<input type="hidden" value="0" name="backupmx">
-					<input type="hidden" value="0" name="relay_all_recipients">
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="description"><?=$lang['edit']['description'];?></label>
-						<div class="col-sm-10">
-							<input type="text" class="form-control" name="description" id="description" value="<?=htmlspecialchars($result['description']);?>">
-						</div>
-					</div>
-					<?php
-					if ($_SESSION['mailcow_cc_role'] == "admin") {
-					?>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="aliases"><?=$lang['edit']['max_aliases'];?></label>
-						<div class="col-sm-10">
-							<input type="number" class="form-control" name="aliases" id="aliases" value="<?=intval($result['max_num_aliases_for_domain']);?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="mailboxes"><?=$lang['edit']['max_mailboxes'];?></label>
-						<div class="col-sm-10">
-							<input type="number" class="form-control" name="mailboxes" id="mailboxes" value="<?=intval($result['max_num_mboxes_for_domain']);?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="maxquota"><?=$lang['edit']['max_quota'];?></label>
-						<div class="col-sm-10">
-							<input type="number" class="form-control" name="maxquota" id="maxquota" value="<?=intval($result['max_quota_for_mbox'] / 1048576);?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="quota"><?=$lang['edit']['domain_quota'];?></label>
-						<div class="col-sm-10">
-							<input type="number" class="form-control" name="quota" id="quota" value="<?=intval($result['max_quota_for_domain'] / 1048576);?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="quota">Relayhost</label>
-						<div class="col-sm-10">
-              <select name="relayhost" id="relayhost" class="form-control">
+if (isset($_SESSION['mailcow_cc_role'])) {
+  if ($_SESSION['mailcow_cc_role'] == "admin"  || $_SESSION['mailcow_cc_role'] == "domainadmin") {
+      if (isset($_GET["alias"]) &&
+        !empty($_GET["alias"])) {
+          $alias = $_GET["alias"];
+          $result = mailbox('get', 'alias_details', $alias);
+          if (!empty($result)) {
+          ?>
+            <h4><?=$lang['edit']['alias'];?></h4>
+            <br />
+            <form class="form-horizontal" data-id="editalias" role="form" method="post">
+              <input type="hidden" value="0" name="active">
+              <div class="form-group">
+                <label class="control-label col-sm-2" for="goto"><?=$lang['edit']['target_address'];?></label>
+                <div class="col-sm-10">
+                  <textarea class="form-control" autocapitalize="none" autocorrect="off" rows="10" id="goto" name="goto"><?=htmlspecialchars($result['goto']) ?></textarea>
+                </div>
+              </div>
+              <div class="form-group">
+                <div class="col-sm-offset-2 col-sm-10">
+                  <div class="checkbox">
+                  <label><input type="checkbox" value="1" name="active" <?php if (isset($result['active_int']) && $result['active_int']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
+                  </div>
+                </div>
+              </div>
+              <div class="form-group">
+                <div class="col-sm-offset-2 col-sm-10">
+                  <button class="btn btn-success" id="edit_selected" data-id="editalias" data-item="<?=$alias;?>" data-api-url='edit/alias' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
+                </div>
+              </div>
+            </form>
+          <?php
+          }
+          else {
+          ?>
+            <div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
+          <?php
+          }
+      }
+      elseif (isset($_GET['domainadmin']) &&
+          ctype_alnum(str_replace(array('_', '.', '-'), '', $_GET["domainadmin"])) &&
+          !empty($_GET["domainadmin"]) &&
+          $_GET["domainadmin"] != 'admin' &&
+          $_SESSION['mailcow_cc_role'] == "admin") {
+          $domain_admin = $_GET["domainadmin"];
+          $result = domain_admin('details', $domain_admin);
+          if (!empty($result)) {
+          ?>
+          <h4><?=$lang['edit']['domain_admin'];?></h4>
+          <br />
+          <form class="form-horizontal" data-id="editdomainadmin" role="form" method="post">
+            <input type="hidden" value="0" name="active">
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="username_new"><?=$lang['edit']['username'];?></label>
+              <div class="col-sm-10">
+                <input class="form-control" type="text" name="username_new" value="<?=htmlspecialchars($domain_admin);?>" />
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="domains"><?=$lang['edit']['domains'];?></label>
+              <div class="col-sm-10">
+                <select id="domains" name="domains" multiple required>
                 <?php
                 <?php
-                foreach ($rlyhosts as $rlyhost) {
+                foreach ($result['selected_domains'] as $domain):
                 ?>
                 ?>
-                <option value="<?=$rlyhost['id'];?>" <?=($result['relayhost'] == $rlyhost['id']) ? 'selected' : null;?>>ID <?=$rlyhost['id'];?>: <?=$rlyhost['hostname'];?> (<?=$rlyhost['username'];?>)</option>
+                  <option selected><?=htmlspecialchars($domain);?></option>
                 <?php
                 <?php
-                }
+                endforeach;
+                foreach ($result['unselected_domains'] as $domain):
                 ?>
                 ?>
-                <option value="" <?=($result['relayhost'] == "0") ? 'selected' : null;?>>None</option>
-              </select>
+                  <option><?=htmlspecialchars($domain);?></option>
+                <?php
+                endforeach;
+                ?>
+                </select>
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="password"><?=$lang['edit']['password'];?></label>
+              <div class="col-sm-10">
+              <input type="password" class="form-control" name="password" id="password" placeholder="">
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="password2"><?=$lang['edit']['password_repeat'];?></label>
+              <div class="col-sm-10">
+              <input type="password" class="form-control" name="password2" id="password2">
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <div class="checkbox">
+                <label><input type="checkbox" value="1" name="active" <?php if (isset($result['active_int']) && $result['active_int']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
+                </div>
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <div class="checkbox">
+                <label><input type="checkbox" value="1" name="disable_tfa"> <?=$lang['tfa']['disable_tfa'];?></label>
+                </div>
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <button class="btn btn-success" id="edit_selected" data-id="editdomainadmin" data-item="<?=$domain_admin;?>" data-api-url='edit/domain-admin' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
+              </div>
+            </div>
+          </form>
+        <?php
+        }
+        else {
+        ?>
+          <div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
+        <?php
+        }
+    }
+    elseif (isset($_GET['domain']) &&
+      is_valid_domain_name($_GET["domain"]) &&
+      !empty($_GET["domain"])) {
+        $domain = $_GET["domain"];
+        $result = mailbox('get', 'domain_details', $domain);
+        $rl = mailbox('get', 'domain_ratelimit', $domain);
+        $rlyhosts = relayhost('get');
+        if (!empty($result)) {
+        ?>
+          <h4><?=$lang['edit']['domain'];?></h4>
+          <form data-id="editdomain" class="form-horizontal" role="form" method="post">
+            <input type="hidden" value="0" name="active">
+            <input type="hidden" value="0" name="backupmx">
+            <input type="hidden" value="0" name="relay_all_recipients">
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="description"><?=$lang['edit']['description'];?></label>
+              <div class="col-sm-10">
+                <input type="text" class="form-control" name="description" id="description" value="<?=htmlspecialchars($result['description']);?>">
+              </div>
+            </div>
+            <?php
+            if ($_SESSION['mailcow_cc_role'] == "admin") {
+            ?>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="aliases"><?=$lang['edit']['max_aliases'];?></label>
+              <div class="col-sm-10">
+                <input type="number" class="form-control" name="aliases" id="aliases" value="<?=intval($result['max_num_aliases_for_domain']);?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="mailboxes"><?=$lang['edit']['max_mailboxes'];?></label>
+              <div class="col-sm-10">
+                <input type="number" class="form-control" name="mailboxes" id="mailboxes" value="<?=intval($result['max_num_mboxes_for_domain']);?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="maxquota"><?=$lang['edit']['max_quota'];?></label>
+              <div class="col-sm-10">
+                <input type="number" class="form-control" name="maxquota" id="maxquota" value="<?=intval($result['max_quota_for_mbox'] / 1048576);?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="quota"><?=$lang['edit']['domain_quota'];?></label>
+              <div class="col-sm-10">
+                <input type="number" class="form-control" name="quota" id="quota" value="<?=intval($result['max_quota_for_domain'] / 1048576);?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="quota">Relayhost</label>
+              <div class="col-sm-10">
+                <select name="relayhost" id="relayhost" class="form-control">
+                  <?php
+                  foreach ($rlyhosts as $rlyhost) {
+                  ?>
+                  <option value="<?=$rlyhost['id'];?>" <?=($result['relayhost'] == $rlyhost['id']) ? 'selected' : null;?>>ID <?=$rlyhost['id'];?>: <?=$rlyhost['hostname'];?> (<?=$rlyhost['username'];?>)</option>
+                  <?php
+                  }
+                  ?>
+                  <option value="" <?=($result['relayhost'] == "0") ? 'selected' : null;?>>None</option>
+                </select>
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2"><?=$lang['edit']['backup_mx_options'];?></label>
+              <div class="col-sm-10">
+                <div class="checkbox">
+                  <label><input type="checkbox" value="1" name="backupmx" <?=(isset($result['backupmx_int']) && $result['backupmx_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['relay_domain'];?></label>
+                  <br />
+                  <label><input type="checkbox" value="1" name="relay_all_recipients" <?=(isset($result['relay_all_recipients_int']) && $result['relay_all_recipients_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['relay_all'];?></label>
+                  <p><?=$lang['edit']['relay_all_info'];?></p>
+                </div>
+              </div>
+            </div>
+            <?php
+            }
+            ?>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <div class="checkbox">
+                  <label><input type="checkbox" value="1" name="active" <?=(isset($result['active_int']) && $result['active_int']=="1") ? "checked" : null;?> <?=($_SESSION['mailcow_cc_role'] == "admin") ? null : "disabled";?>> <?=$lang['edit']['active'];?></label>
+                </div>
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <button class="btn btn-success" id="edit_selected" data-id="editdomain" data-item="<?=$domain;?>" data-api-url='edit/domain' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
+              </div>
+            </div>
+          </form>
+          <?php
+          if (!empty($dkim = dkim('details', $domain))) {
+          ?>
+          <hr>
+          <div class="row">
+            <div class="col-xs-2">
+              <p>Domain: <strong><?=htmlspecialchars($result['domain_name']);?></strong> (<?=$dkim['dkim_selector'];?>._domainkey)</p>
+            </div>
+            <div class="col-xs-10">
+              <pre><?=$dkim['dkim_txt'];?></pre>
             </div>
             </div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2"><?=$lang['edit']['backup_mx_options'];?></label>
-						<div class="col-sm-10">
-							<div class="checkbox">
-								<label><input type="checkbox" value="1" name="backupmx" <?=(isset($result['backupmx_int']) && $result['backupmx_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['relay_domain'];?></label>
-								<br />
-								<label><input type="checkbox" value="1" name="relay_all_recipients" <?=(isset($result['relay_all_recipients_int']) && $result['relay_all_recipients_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['relay_all'];?></label>
-								<p><?=$lang['edit']['relay_all_info'];?></p>
-							</div>
-						</div>
-					</div>
-					<?php
-					}
-					?>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-							<div class="checkbox">
-								<label><input type="checkbox" value="1" name="active" <?=(isset($result['active_int']) && $result['active_int']=="1") ? "checked" : null;?> <?=($_SESSION['mailcow_cc_role'] == "admin") ? null : "disabled";?>> <?=$lang['edit']['active'];?></label>
-							</div>
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-              <button class="btn btn-success" id="edit_selected" data-id="editdomain" data-item="<?=$domain;?>" data-api-url='edit/domain' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
-						</div>
-					</div>
-				</form>
-				<?php
-        if (!empty($dkim = dkim('details', $domain))) {
-				?>
-        <hr>
-        <div class="row">
-          <div class="col-xs-2">
-            <p>Domain: <strong><?=htmlspecialchars($result['domain_name']);?></strong> (<?=$dkim['dkim_selector'];?>._domainkey)</p>
-          </div>
-          <div class="col-xs-10">
-            <pre><?=$dkim['dkim_txt'];?></pre>
           </div>
           </div>
+          <?php
+          }
+          ?>
+      <hr>
+      <!--
+      <form data-id="domratelimit" class="form-inline well" method="post">
+        <div class="form-group">
+          <label class="control-label">Ratelimit</label>
+          <input name="rl_value" id="rl_value" type="number" value="<?=(!empty($rl['value'])) ? $rl['value'] : null;?>" class="form-control" placeholder="disabled">
         </div>
         </div>
-				<?php
-				}
-        ?>
-		<hr>
-    <!--
-    <form data-id="domratelimit" class="form-inline well" method="post">
-      <div class="form-group">
-        <label class="control-label">Ratelimit</label>
-        <input name="rl_value" id="rl_value" type="number" value="<?=(!empty($rl['value'])) ? $rl['value'] : null;?>" class="form-control" placeholder="disabled">
-      </div>
-      <div class="form-group">
-        <select name="rl_frame" id="rl_frame" class="form-control">
-          <option value="s" <?=(isset($rl['frame']) && $rl['frame'] == 's') ? 'selected' : null;?>>msgs / second</option>
-          <option value="m" <?=(isset($rl['frame']) && $rl['frame'] == 'm') ? 'selected' : null;?>>msgs / minute</option>
-          <option value="h" <?=(isset($rl['frame']) && $rl['frame'] == 'h') ? 'selected' : null;?>>msgs / hour</option>
-        </select>
-      </div>
-      <div class="form-group">
-        <button class="btn btn-default" id="edit_selected" data-id="domratelimit" data-item="<?=$domain;?>" data-api-url='edit/domain-ratelimit' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
-      </div>
-    </form>
-		<hr>
-    -->
-		<div class="row">
-			<div class="col-sm-6">
-				<h4><?=$lang['user']['spamfilter_wl'];?></h4>
-        <p><?=$lang['user']['spamfilter_wl_desc'];?></p>
-        <div class="table-responsive">
-          <table class="table table-striped table-condensed" id="wl_policy_domain_table"></table>
+        <div class="form-group">
+          <select name="rl_frame" id="rl_frame" class="form-control">
+            <option value="s" <?=(isset($rl['frame']) && $rl['frame'] == 's') ? 'selected' : null;?>>msgs / second</option>
+            <option value="m" <?=(isset($rl['frame']) && $rl['frame'] == 'm') ? 'selected' : null;?>>msgs / minute</option>
+            <option value="h" <?=(isset($rl['frame']) && $rl['frame'] == 'h') ? 'selected' : null;?>>msgs / hour</option>
+          </select>
         </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="policy_wl_domain" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
-            <a class="btn btn-sm btn-danger" id="delete_selected" data-id="policy_wl_domain" data-api-url='delete/domain-policy' href="#"><?=$lang['mailbox']['remove'];?></a></li>
-            </ul>
-          </div>
+        <div class="form-group">
+          <button class="btn btn-default" id="edit_selected" data-id="domratelimit" data-item="<?=$domain;?>" data-api-url='edit/domain-ratelimit' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
         </div>
         </div>
-        <form class="form-inline" data-id="add_wl_policy_domain">
-          <div class="input-group">
-            <input type="text" class="form-control" name="object_from" id="object_from" placeholder="*@example.org" required>
-            <span class="input-group-btn">
-              <button class="btn btn-default" id="add_item" data-id="add_wl_policy_domain" data-api-url='add/domain-policy' data-api-attr='{"domain":"<?= $domain; ?>","object_list":"wl"}' href="#"><?=$lang['user']['spamfilter_table_add'];?></button>
-            </span>
+      </form>
+      <hr>
+      -->
+      <div class="row">
+        <div class="col-sm-6">
+          <h4><?=$lang['user']['spamfilter_wl'];?></h4>
+          <p><?=$lang['user']['spamfilter_wl_desc'];?></p>
+          <div class="table-responsive">
+            <table class="table table-striped table-condensed" id="wl_policy_domain_table"></table>
           </div>
           </div>
-        </form>
-      </div>
-			<div class="col-sm-6">
-				<h4><?=$lang['user']['spamfilter_bl'];?></h4>
-        <p><?=$lang['user']['spamfilter_bl_desc'];?></p>
-        <div class="table-responsive">
-          <table class="table table-striped table-condensed" id="bl_policy_domain_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="policy_bl_domain" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
-            <a class="btn btn-sm btn-danger" id="delete_selected" data-id="policy_bl_domain" data-api-url='delete/domain-policy' href="#"><?=$lang['mailbox']['remove'];?></a></li>
-            </ul>
+          <div class="mass-actions-user">
+            <div class="btn-group">
+              <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="policy_wl_domain" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+              <a class="btn btn-sm btn-danger" id="delete_selected" data-id="policy_wl_domain" data-api-url='delete/domain-policy' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+              </ul>
+            </div>
           </div>
           </div>
+          <form class="form-inline" data-id="add_wl_policy_domain">
+            <div class="input-group">
+              <input type="text" class="form-control" name="object_from" id="object_from" placeholder="*@example.org" required>
+              <span class="input-group-btn">
+                <button class="btn btn-default" id="add_item" data-id="add_wl_policy_domain" data-api-url='add/domain-policy' data-api-attr='{"domain":"<?= $domain; ?>","object_list":"wl"}' href="#"><?=$lang['user']['spamfilter_table_add'];?></button>
+              </span>
+            </div>
+          </form>
         </div>
         </div>
-        <form class="form-inline" data-id="add_bl_policy_domain">
-          <div class="input-group">
-            <input type="text" class="form-control" name="object_from" id="object_from" placeholder="*@example.org" required>
-            <span class="input-group-btn">
-              <button class="btn btn-default" id="add_item" data-id="add_bl_policy_domain" data-api-url='add/domain-policy' data-api-attr='{"domain":"<?= $domain; ?>","object_list":"bl"}' href="#"><?=$lang['user']['spamfilter_table_add'];?></button>
-            </span>
+        <div class="col-sm-6">
+          <h4><?=$lang['user']['spamfilter_bl'];?></h4>
+          <p><?=$lang['user']['spamfilter_bl_desc'];?></p>
+          <div class="table-responsive">
+            <table class="table table-striped table-condensed" id="bl_policy_domain_table"></table>
           </div>
           </div>
-        </form>
+          <div class="mass-actions-user">
+            <div class="btn-group">
+              <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="policy_bl_domain" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+              <a class="btn btn-sm btn-danger" id="delete_selected" data-id="policy_bl_domain" data-api-url='delete/domain-policy' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+              </ul>
+            </div>
+          </div>
+          <form class="form-inline" data-id="add_bl_policy_domain">
+            <div class="input-group">
+              <input type="text" class="form-control" name="object_from" id="object_from" placeholder="*@example.org" required>
+              <span class="input-group-btn">
+                <button class="btn btn-default" id="add_item" data-id="add_bl_policy_domain" data-api-url='add/domain-policy' data-api-attr='{"domain":"<?= $domain; ?>","object_list":"bl"}' href="#"><?=$lang['user']['spamfilter_table_add'];?></button>
+              </span>
+            </div>
+          </form>
+        </div>
       </div>
       </div>
-    </div>
+          <?php
+        }
+        else {
+        ?>
+          <div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
+        <?php
+        }
+    }
+    elseif (isset($_GET['aliasdomain']) &&
+      is_valid_domain_name($_GET["aliasdomain"]) &&
+      !empty($_GET["aliasdomain"])) {
+        $alias_domain = $_GET["aliasdomain"];
+        $result = mailbox('get', 'alias_domain_details', $alias_domain);
+        // $rl = mailbox('get', 'domain_ratelimit', $alias_domain);
+        if (!empty($result)) {
+        ?>
+          <h4><?=$lang['edit']['edit_alias_domain'];?></h4>
+          <form class="form-horizontal" data-id="editaliasdomain" role="form" method="post">
+            <input type="hidden" value="0" name="active">
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="target_domain"><?=$lang['edit']['target_domain'];?></label>
+              <div class="col-sm-10">
+                <input type="text" class="form-control" name="target_domain" id="target_domain" value="<?=htmlspecialchars($result['target_domain']);?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <div class="checkbox">
+                  <label><input type="checkbox" value="1" name="active" <?=(isset($result['active_int']) && $result['active_int']=="1") ?  "checked" : null ?>> <?=$lang['edit']['active'];?></label>
+                </div>
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <button class="btn btn-success" id="edit_selected" data-id="editaliasdomain" data-item="<?=$alias_domain;?>" data-api-url='edit/alias-domain' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
+              </div>
+            </div>
+          </form>
+          <!--
+          <hr>
+          <form data-id="domratelimit" class="form-inline well" method="post">
+            <div class="form-group">
+              <label class="control-label">Ratelimit</label>
+              <input name="rl_value" id="rl_value" type="number" value="<?=(!empty($rl['value'])) ? $rl['value'] : null;?>" class="form-control" placeholder="disabled">
+            </div>
+            <div class="form-group">
+              <select name="rl_frame" id="rl_frame" class="form-control">
+                <option value="s" <?=(isset($rl['frame']) && $rl['frame'] == 's') ? 'selected' : null;?>>msgs / second</option>
+                <option value="m" <?=(isset($rl['frame']) && $rl['frame'] == 'm') ? 'selected' : null;?>>msgs / minute</option>
+                <option value="h" <?=(isset($rl['frame']) && $rl['frame'] == 'h') ? 'selected' : null;?>>msgs / hour</option>
+              </select>
+            </div>
+            <div class="form-group">
+              <button class="btn btn-default" id="edit_selected" data-id="domratelimit" data-item="<?=$alias_domain;?>" data-api-url='edit/domain-ratelimit' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
+            </div>
+          </form>
+          -->
+          <?php
+          if (!empty($dkim = dkim('details', $alias_domain))) {
+          ?>
+          <hr>
+          <div class="row">
+            <div class="col-xs-2">
+              <p>Domain: <strong><?=htmlspecialchars($result['alias_domain']);?></strong> (<?=$dkim['dkim_selector'];?>._domainkey)</p>
+            </div>
+            <div class="col-xs-10">
+            <pre><?=$dkim['dkim_txt'];?></pre>
+            </div>
+          </div>
+          <?php
+          }
+        }
+        else {
+        ?>
+          <div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
         <?php
         <?php
-			}
-			else {
-			?>
-				<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
-			<?php
-			}
-	}
-	elseif (isset($_GET['aliasdomain']) &&
-		is_valid_domain_name($_GET["aliasdomain"]) &&
-		!empty($_GET["aliasdomain"])) {
-			$alias_domain = $_GET["aliasdomain"];
-      $result = mailbox('get', 'alias_domain_details', $alias_domain);
-      // $rl = mailbox('get', 'domain_ratelimit', $alias_domain);
+        }
+    }
+    elseif (isset($_GET['mailbox']) && filter_var($_GET["mailbox"], FILTER_VALIDATE_EMAIL) && !empty($_GET["mailbox"])) {
+      $mailbox = $_GET["mailbox"];
+      $result = mailbox('get', 'mailbox_details', $mailbox);
       if (!empty($result)) {
       if (!empty($result)) {
-			?>
-				<h4><?=$lang['edit']['edit_alias_domain'];?></h4>
-				<form class="form-horizontal" data-id="editaliasdomain" role="form" method="post">
-					<input type="hidden" value="0" name="active">
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="target_domain"><?=$lang['edit']['target_domain'];?></label>
-						<div class="col-sm-10">
-							<input type="text" class="form-control" name="target_domain" id="target_domain" value="<?=htmlspecialchars($result['target_domain']);?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-							<div class="checkbox">
-								<label><input type="checkbox" value="1" name="active" <?=(isset($result['active_int']) && $result['active_int']=="1") ?  "checked" : null ?>> <?=$lang['edit']['active'];?></label>
-							</div>
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-              <button class="btn btn-success" id="edit_selected" data-id="editaliasdomain" data-item="<?=$alias_domain;?>" data-api-url='edit/alias-domain' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
-						</div>
-					</div>
-				</form>
-        <!--
-        <hr>
-        <form data-id="domratelimit" class="form-inline well" method="post">
+        ?>
+        <h4><?=$lang['edit']['mailbox'];?></h4>
+        <form class="form-horizontal" data-id="editmailbox" role="form" method="post">
+          <input type="hidden" value="0" name="sender_acl">
+          <input type="hidden" value="0" name="active">
           <div class="form-group">
           <div class="form-group">
-            <label class="control-label">Ratelimit</label>
-            <input name="rl_value" id="rl_value" type="number" value="<?=(!empty($rl['value'])) ? $rl['value'] : null;?>" class="form-control" placeholder="disabled">
+            <label class="control-label col-sm-2" for="name"><?=$lang['edit']['full_name'];?>:</label>
+            <div class="col-sm-10">
+            <input type="text" class="form-control" name="name" id="name" value="<?=htmlspecialchars($result['name'], ENT_QUOTES, 'UTF-8');?>">
+            </div>
           </div>
           </div>
           <div class="form-group">
           <div class="form-group">
-            <select name="rl_frame" id="rl_frame" class="form-control">
-              <option value="s" <?=(isset($rl['frame']) && $rl['frame'] == 's') ? 'selected' : null;?>>msgs / second</option>
-              <option value="m" <?=(isset($rl['frame']) && $rl['frame'] == 'm') ? 'selected' : null;?>>msgs / minute</option>
-              <option value="h" <?=(isset($rl['frame']) && $rl['frame'] == 'h') ? 'selected' : null;?>>msgs / hour</option>
-            </select>
+            <label class="control-label col-sm-2" for="quota"><?=$lang['edit']['quota_mb'];?>:
+              <br /><span id="quotaBadge" class="badge">max. <?=intval($result['max_new_quota'] / 1048576)?> MiB</span>
+            </label>
+            <div class="col-sm-10">
+              <input type="number" name="quota" id="quota" id="destroyable" style="width:100%" min="1" max="<?=intval($result['max_new_quota'] / 1048576);?>" value="<?=intval($result['quota']) / 1048576;?>" class="form-control">
+            </div>
           </div>
           </div>
           <div class="form-group">
           <div class="form-group">
-            <button class="btn btn-default" id="edit_selected" data-id="domratelimit" data-item="<?=$alias_domain;?>" data-api-url='edit/domain-ratelimit' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
-          </div>
-        </form>
-        -->
-				<?php
-        if (!empty($dkim = dkim('details', $alias_domain))) {
-				?>
-        <hr>
-        <div class="row">
-          <div class="col-xs-2">
-            <p>Domain: <strong><?=htmlspecialchars($result['alias_domain']);?></strong> (<?=$dkim['dkim_selector'];?>._domainkey)</p>
-          </div>
-          <div class="col-xs-10">
-          <pre><?=$dkim['dkim_txt'];?></pre>
-          </div>
-        </div>
-				<?php
-				}
-			}
-			else {
-			?>
-				<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
-			<?php
-			}
-	}
-	elseif (isset($_GET['mailbox']) && filter_var($_GET["mailbox"], FILTER_VALIDATE_EMAIL) && !empty($_GET["mailbox"])) {
-    $mailbox = $_GET["mailbox"];
-    $result = mailbox('get', 'mailbox_details', $mailbox);
-    if (!empty($result)) {
-      ?>
-      <h4><?=$lang['edit']['mailbox'];?></h4>
-      <form class="form-horizontal" data-id="editmailbox" role="form" method="post">
-				<input type="hidden" value="0" name="sender_acl">
-				<input type="hidden" value="0" name="active">
-        <div class="form-group">
-          <label class="control-label col-sm-2" for="name"><?=$lang['edit']['full_name'];?>:</label>
-          <div class="col-sm-10">
-          <input type="text" class="form-control" name="name" id="name" value="<?=htmlspecialchars($result['name'], ENT_QUOTES, 'UTF-8');?>">
-          </div>
-        </div>
-        <div class="form-group">
-          <label class="control-label col-sm-2" for="quota"><?=$lang['edit']['quota_mb'];?>:
-            <br /><span id="quotaBadge" class="badge">max. <?=intval($result['max_new_quota'] / 1048576)?> MiB</span>
-          </label>
-          <div class="col-sm-10">
-            <input type="number" name="quota" id="quota" id="destroyable" style="width:100%" min="1" max="<?=intval($result['max_new_quota'] / 1048576);?>" value="<?=intval($result['quota']) / 1048576;?>" class="form-control">
-          </div>
-        </div>
-        <div class="form-group">
-          <label class="control-label col-sm-2" for="sender_acl"><?=$lang['edit']['sender_acl'];?>:</label>
-          <div class="col-sm-10">
-            <select data-width="100%" style="width:100%" id="sender_acl" name="sender_acl" size="10" multiple>
-            <?php
-            $sender_acl_handles = mailbox('get', 'sender_acl_handles', $mailbox);
-
-            foreach ($sender_acl_handles['sender_acl_domains']['ro'] as $domain):
-              ?>
-              <option data-subtext="Admin" value="<?=htmlspecialchars($domain);?>" disabled selected><?=htmlspecialchars(sprintf($lang['edit']['dont_check_sender_acl'], $domain));?></option>
+            <label class="control-label col-sm-2" for="sender_acl"><?=$lang['edit']['sender_acl'];?>:</label>
+            <div class="col-sm-10">
+              <select data-width="100%" style="width:100%" id="sender_acl" name="sender_acl" size="10" multiple>
               <?php
               <?php
-            endforeach;
+              $sender_acl_handles = mailbox('get', 'sender_acl_handles', $mailbox);
 
 
-            foreach ($sender_acl_handles['sender_acl_addresses']['ro'] as $domain):
-              ?>
-            <option data-subtext="Admin" disabled selected><?=htmlspecialchars($alias);?></option>
-              <?php
-            endforeach;
+              foreach ($sender_acl_handles['sender_acl_domains']['ro'] as $domain):
+                ?>
+                <option data-subtext="Admin" value="<?=htmlspecialchars($domain);?>" disabled selected><?=htmlspecialchars(sprintf($lang['edit']['dont_check_sender_acl'], $domain));?></option>
+                <?php
+              endforeach;
 
 
-            foreach ($sender_acl_handles['fixed_sender_aliases'] as $alias):
-              ?>
-              <option data-subtext="Alias" disabled selected><?=htmlspecialchars($alias);?></option>
-              <?php
-            endforeach;
+              foreach ($sender_acl_handles['sender_acl_addresses']['ro'] as $domain):
+                ?>
+              <option data-subtext="Admin" disabled selected><?=htmlspecialchars($alias);?></option>
+                <?php
+              endforeach;
 
 
-            foreach ($sender_acl_handles['sender_acl_domains']['rw'] as $domain):
-              ?>
-              <option value="<?=htmlspecialchars($domain);?>" selected><?=htmlspecialchars(sprintf($lang['edit']['dont_check_sender_acl'], $domain));?></option>
-              <?php
-            endforeach;
+              foreach ($sender_acl_handles['fixed_sender_aliases'] as $alias):
+                ?>
+                <option data-subtext="Alias" disabled selected><?=htmlspecialchars($alias);?></option>
+                <?php
+              endforeach;
 
 
-            foreach ($sender_acl_handles['sender_acl_domains']['selectable'] as $domain):
-              ?>
-              <option value="<?=htmlspecialchars($domain);?>"><?=htmlspecialchars(sprintf($lang['edit']['dont_check_sender_acl'], $domain));?></option>
-              <?php
-            endforeach;
+              foreach ($sender_acl_handles['sender_acl_domains']['rw'] as $domain):
+                ?>
+                <option value="<?=htmlspecialchars($domain);?>" selected><?=htmlspecialchars(sprintf($lang['edit']['dont_check_sender_acl'], $domain));?></option>
+                <?php
+              endforeach;
 
 
-            foreach ($sender_acl_handles['sender_acl_addresses']['rw'] as $address):
-              ?>
-                <option selected><?=htmlspecialchars($address);?></option>
-              <?php
-            endforeach;
+              foreach ($sender_acl_handles['sender_acl_domains']['selectable'] as $domain):
+                ?>
+                <option value="<?=htmlspecialchars($domain);?>"><?=htmlspecialchars(sprintf($lang['edit']['dont_check_sender_acl'], $domain));?></option>
+                <?php
+              endforeach;
 
 
-            foreach ($sender_acl_handles['sender_acl_addresses']['selectable'] as $address):
-              ?>
-                <option><?=htmlspecialchars($address);?></option>
-              <?php
-            endforeach;
+              foreach ($sender_acl_handles['sender_acl_addresses']['rw'] as $address):
+                ?>
+                  <option selected><?=htmlspecialchars($address);?></option>
+                <?php
+              endforeach;
 
 
-            ?>
-            </select>
+              foreach ($sender_acl_handles['sender_acl_addresses']['selectable'] as $address):
+                ?>
+                  <option><?=htmlspecialchars($address);?></option>
+                <?php
+              endforeach;
+
+              ?>
+              </select>
+            </div>
           </div>
           </div>
-        </div>
-        <div class="form-group">
-          <label class="control-label col-sm-2" for="password"><?=$lang['edit']['password'];?></label>
-          <div class="col-sm-10">
-          <input type="password" class="form-control" name="password" id="password" placeholder="<?=$lang['edit']['unchanged_if_empty'];?>">
+          <div class="form-group">
+            <label class="control-label col-sm-2" for="password"><?=$lang['edit']['password'];?></label>
+            <div class="col-sm-10">
+            <input type="password" class="form-control" name="password" id="password" placeholder="<?=$lang['edit']['unchanged_if_empty'];?>">
+            </div>
           </div>
           </div>
-        </div>
-        <div class="form-group">
-          <label class="control-label col-sm-2" for="password2"><?=$lang['edit']['password_repeat'];?></label>
-          <div class="col-sm-10">
-          <input type="password" class="form-control" name="password2" id="password2">
+          <div class="form-group">
+            <label class="control-label col-sm-2" for="password2"><?=$lang['edit']['password_repeat'];?></label>
+            <div class="col-sm-10">
+            <input type="password" class="form-control" name="password2" id="password2">
+            </div>
           </div>
           </div>
-        </div>
-        <div class="form-group">
-          <div class="col-sm-offset-2 col-sm-10">
-            <div class="checkbox">
-            <label><input type="checkbox" value="1" name="active" <?=($result['active_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['active'];?></label>
+          <div class="form-group">
+            <div class="col-sm-offset-2 col-sm-10">
+              <div class="checkbox">
+              <label><input type="checkbox" value="1" name="active" <?=($result['active_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['active'];?></label>
+              </div>
             </div>
             </div>
           </div>
           </div>
-        </div>
-        <div class="form-group">
-          <div class="col-sm-offset-2 col-sm-10">
-            <button class="btn btn-success" id="edit_selected" data-id="editmailbox" data-item="<?=htmlspecialchars($result['username']);?>" data-api-url='edit/mailbox' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
+          <div class="form-group">
+            <div class="col-sm-offset-2 col-sm-10">
+              <button class="btn btn-success" id="edit_selected" data-id="editmailbox" data-item="<?=htmlspecialchars($result['username']);?>" data-api-url='edit/mailbox' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
+            </div>
           </div>
           </div>
-        </div>
-      </form>
-    <?php
+        </form>
+      <?php
+      }
+    }
+    elseif (isset($_GET['relayhost']) && is_numeric($_GET["relayhost"]) && !empty($_GET["relayhost"])) {
+        $relayhost = intval($_GET["relayhost"]);
+        $result = relayhost('details', $relayhost);
+        if (!empty($result)) {
+          ?>
+          <h4><?=$lang['edit']['resource'];?></h4>
+          <form class="form-horizontal" role="form" method="post" data-id="editrelayhost">
+            <input type="hidden" value="0" name="active">
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="hostname"><?=$lang['add']['hostname'];?></label>
+              <div class="col-sm-10">
+                <input type="text" class="form-control" name="hostname" id="hostname" value="<?=htmlspecialchars($result['hostname'], ENT_QUOTES, 'UTF-8');?>" required>
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="username"><?=$lang['add']['username'];?></label>
+              <div class="col-sm-10">
+                <input type="text" class="form-control" name="username" id="username" value="<?=htmlspecialchars($result['username'], ENT_QUOTES, 'UTF-8');?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="password"><?=$lang['add']['password'];?></label>
+              <div class="col-sm-10">
+                <input type="password" class="form-control" name="password" id="password" value="<?=htmlspecialchars($result['password'], ENT_QUOTES, 'UTF-8');?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <div class="checkbox">
+                <label><input type="checkbox" value="1" name="active" <?=($result['active_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['active'];?></label>
+                </div>
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <button class="btn btn-success" id="edit_selected" data-id="editrelayhost" data-item="<?=htmlspecialchars($result['id']);?>" data-api-url='edit/relayhost' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
+              </div>
+            </div>
+          </form>
+        <?php
+        }
+        else {
+        ?>
+          <div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
+        <?php
+        }
+    }
+    elseif (isset($_GET['resource']) && filter_var($_GET["resource"], FILTER_VALIDATE_EMAIL) && !empty($_GET["resource"])) {
+        $resource = $_GET["resource"];
+        $result = mailbox('get', 'resource_details', $resource);
+        if (!empty($result)) {
+          ?>
+          <h4><?=$lang['edit']['resource'];?></h4>
+          <form class="form-horizontal" role="form" method="post" data-id="editresource">
+            <input type="hidden" value="0" name="active">
+            <input type="hidden" value="0" name="multiple_bookings">
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="description"><?=$lang['add']['description'];?></label>
+              <div class="col-sm-10">
+                <input type="text" class="form-control" name="description" id="description" value="<?=htmlspecialchars($result['description'], ENT_QUOTES, 'UTF-8');?>" required>
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="domain"><?=$lang['edit']['kind'];?>:</label>
+              <div class="col-sm-10">
+                <select name="kind" id="kind" title="<?=$lang['edit']['select'];?>" required>
+                  <option value="location" <?=($result['kind'] == "location") ? "selected" : null;?>>Location</option>
+                  <option value="group" <?=($result['kind'] == "group") ? "selected" : null;?>>Group</option>
+                  <option value="thing" <?=($result['kind'] == "thing") ? "selected" : null;?>>Thing</option>
+                </select>
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <div class="checkbox">
+                <label><input type="checkbox" value="1" name="active" <?=($result['active_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['active'];?></label>
+                </div>
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <div class="checkbox">
+                <label><input type="checkbox" value="1" name="multiple_bookings" <?=($result['multiple_bookings_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['multiple_bookings'];?></label>
+                </div>
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <button class="btn btn-success" id="edit_selected" data-id="editresource" data-item="<?=htmlspecialchars($result['name']);?>" data-api-url='edit/resource' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
+              </div>
+            </div>
+          </form>
+        <?php
+        }
+        else {
+        ?>
+          <div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
+        <?php
+        }
     }
     }
   }
   }
-	elseif (isset($_GET['relayhost']) && is_numeric($_GET["relayhost"]) && !empty($_GET["relayhost"])) {
-			$relayhost = intval($_GET["relayhost"]);
-      $result = relayhost('details', $relayhost);
-      if (!empty($result)) {
+  if ($_SESSION['mailcow_cc_role'] == "admin"  || $_SESSION['mailcow_cc_role'] == "domainadmin" || $_SESSION['mailcow_cc_role'] == "user") {
+    if (isset($_GET['syncjob']) &&
+      is_numeric($_GET['syncjob'])) {
+        $id = $_GET["syncjob"];
+        $result = mailbox('get', 'syncjob_details', $id);
+        if (!empty($result)) {
         ?>
         ?>
-				<h4><?=$lang['edit']['resource'];?></h4>
-				<form class="form-horizontal" role="form" method="post" data-id="editrelayhost">
-          <input type="hidden" value="0" name="active">
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="hostname"><?=$lang['add']['hostname'];?></label>
-						<div class="col-sm-10">
-							<input type="text" class="form-control" name="hostname" id="hostname" value="<?=htmlspecialchars($result['hostname'], ENT_QUOTES, 'UTF-8');?>" required>
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="username"><?=$lang['add']['username'];?></label>
-						<div class="col-sm-10">
-							<input type="text" class="form-control" name="username" id="username" value="<?=htmlspecialchars($result['username'], ENT_QUOTES, 'UTF-8');?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="password"><?=$lang['add']['password'];?></label>
-						<div class="col-sm-10">
-							<input type="password" class="form-control" name="password" id="password" value="<?=htmlspecialchars($result['password'], ENT_QUOTES, 'UTF-8');?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-							<div class="checkbox">
-							<label><input type="checkbox" value="1" name="active" <?=($result['active_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['active'];?></label>
-							</div>
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-              <button class="btn btn-success" id="edit_selected" data-id="editrelayhost" data-item="<?=htmlspecialchars($result['id']);?>" data-api-url='edit/relayhost' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
-						</div>
-					</div>
-				</form>
-			<?php
-			}
-			else {
-			?>
-				<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
-			<?php
-			}
-	}
-	elseif (isset($_GET['resource']) && filter_var($_GET["resource"], FILTER_VALIDATE_EMAIL) && !empty($_GET["resource"])) {
-			$resource = $_GET["resource"];
-      $result = mailbox('get', 'resource_details', $resource);
-      if (!empty($result)) {
+          <h4><?=$lang['edit']['syncjob'];?></h4>
+          <form class="form-horizontal" data-id="editsyncjob" role="form" method="post">
+            <input type="hidden" value="0" name="delete2duplicates">
+            <input type="hidden" value="0" name="delete1">
+            <input type="hidden" value="0" name="active">
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="host1"><?=$lang['edit']['hostname'];?></label>
+              <div class="col-sm-10">
+              <input type="text" class="form-control" name="host1" id="host1" value="<?=htmlspecialchars($result['host1'], ENT_QUOTES, 'UTF-8');?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="port1">Port</label>
+              <div class="col-sm-10">
+              <input type="number" class="form-control" name="port1" id="port1" min="1" max="65535" value="<?=htmlspecialchars($result['port1'], ENT_QUOTES, 'UTF-8');?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="user1"><?=$lang['edit']['username'];?></label>
+              <div class="col-sm-10">
+              <input type="text" class="form-control" name="user1" id="user1" value="<?=htmlspecialchars($result['user1'], ENT_QUOTES, 'UTF-8');?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="password1"><?=$lang['edit']['password'];?></label>
+              <div class="col-sm-10">
+              <input type="password" class="form-control" name="password1" id="password1" value="<?=htmlspecialchars($result['password1'], ENT_QUOTES, 'UTF-8');?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="enc1"><?=$lang['edit']['encryption'];?>:</label>
+              <div class="col-sm-10">
+                <select id="enc1" name="enc1">
+                  <option <?=($result['enc1'] == "TLS") ? "selected" : null;?>>TLS</option>
+                  <option <?=($result['enc1'] == "SSL") ? "selected" : null;?>>SSL</option>
+                  <option <?=($result['enc1'] == "PLAIN") ? "selected" : null;?>>PLAIN</option>
+                </select>
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="mins_interval"><?=$lang['edit']['mins_interval'];?></label>
+              <div class="col-sm-10">
+                <input type="number" class="form-control" name="mins_interval" min="10" max="3600" value="<?=htmlspecialchars($result['mins_interval'], ENT_QUOTES, 'UTF-8');?>" required>
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="subfolder2"><?=$lang['edit']['subfolder2'];?></label>
+              <div class="col-sm-10">
+              <input type="text" class="form-control" name="subfolder2" id="subfolder2" value="<?=htmlspecialchars($result['subfolder2'], ENT_QUOTES, 'UTF-8');?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="maxage"><?=$lang['edit']['maxage'];?></label>
+              <div class="col-sm-10">
+              <input type="number" class="form-control" name="maxage" id="maxage" value="<?=htmlspecialchars($result['maxage'], ENT_QUOTES, 'UTF-8');?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <label class="control-label col-sm-2" for="exclude"><?=$lang['edit']['exclude'];?></label>
+              <div class="col-sm-10">
+              <input type="text" class="form-control" name="exclude" id="exclude" value="<?=htmlspecialchars($result['exclude'], ENT_QUOTES, 'UTF-8');?>">
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <div class="checkbox">
+                <label><input type="checkbox" value="1" name="delete2duplicates" <?=($result['delete2duplicates']=="1") ? "checked" : "";?>> <?=$lang['edit']['delete2duplicates'];?></label>
+                </div>
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <div class="checkbox">
+                <label><input type="checkbox" value="1" name="delete1" <?=($result['delete1']=="1") ? "checked" : "";?>> <?=$lang['edit']['delete1'];?></label>
+                </div>
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <div class="checkbox">
+                <label><input type="checkbox" value="1" name="active" <?=($result['active_int']=="1") ? "checked" : "";?>> <?=$lang['edit']['active'];?></label>
+                </div>
+              </div>
+            </div>
+            <div class="form-group">
+              <div class="col-sm-offset-2 col-sm-10">
+                <button class="btn btn-success" id="edit_selected" data-id="editsyncjob" data-item="<?=htmlspecialchars($result['id']);?>" data-api-url='edit/syncjob' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
+              </div>
+            </div>
+          </form>
+        <?php
+        }
+        else {
         ?>
         ?>
-				<h4><?=$lang['edit']['resource'];?></h4>
-				<form class="form-horizontal" role="form" method="post" data-id="editresource">
-          <input type="hidden" value="0" name="active">
-          <input type="hidden" value="0" name="multiple_bookings">
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="description"><?=$lang['add']['description'];?></label>
-						<div class="col-sm-10">
-							<input type="text" class="form-control" name="description" id="description" value="<?=htmlspecialchars($result['description'], ENT_QUOTES, 'UTF-8');?>" required>
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="domain"><?=$lang['edit']['kind'];?>:</label>
-						<div class="col-sm-10">
-							<select name="kind" id="kind" title="<?=$lang['edit']['select'];?>" required>
-								<option value="location" <?=($result['kind'] == "location") ? "selected" : null;?>>Location</option>
-								<option value="group" <?=($result['kind'] == "group") ? "selected" : null;?>>Group</option>
-								<option value="thing" <?=($result['kind'] == "thing") ? "selected" : null;?>>Thing</option>
-							</select>
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-							<div class="checkbox">
-							<label><input type="checkbox" value="1" name="active" <?=($result['active_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['active'];?></label>
-							</div>
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-							<div class="checkbox">
-							<label><input type="checkbox" value="1" name="multiple_bookings" <?=($result['multiple_bookings_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['multiple_bookings'];?></label>
-							</div>
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-              <button class="btn btn-success" id="edit_selected" data-id="editresource" data-item="<?=htmlspecialchars($result['name']);?>" data-api-url='edit/resource' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
-						</div>
-					</div>
-				</form>
-			<?php
-			}
-			else {
-			?>
-				<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
-			<?php
-			}
-	}
-	else {
-	?>
-		<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
-	<?php
-	}
-}
-elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "user")) {
-	if (isset($_GET['syncjob']) &&
-    is_numeric($_GET['syncjob'])) {
-			$id = $_GET["syncjob"];
-      $result = mailbox('get', 'syncjob_details', $id);
-      if (!empty($result)) {
-			?>
-				<h4><?=$lang['edit']['syncjob'];?></h4>
-				<form class="form-horizontal" data-id="editsyncjob" role="form" method="post">
-          <input type="hidden" value="0" name="delete2duplicates">
-          <input type="hidden" value="0" name="delete1">
-          <input type="hidden" value="0" name="active">
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="host1"><?=$lang['edit']['hostname'];?></label>
-						<div class="col-sm-10">
-						<input type="text" class="form-control" name="host1" id="host1" value="<?=htmlspecialchars($result['host1'], ENT_QUOTES, 'UTF-8');?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="port1">Port</label>
-						<div class="col-sm-10">
-						<input type="number" class="form-control" name="port1" id="port1" min="1" max="65535" value="<?=htmlspecialchars($result['port1'], ENT_QUOTES, 'UTF-8');?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="user1"><?=$lang['edit']['username'];?></label>
-						<div class="col-sm-10">
-						<input type="text" class="form-control" name="user1" id="user1" value="<?=htmlspecialchars($result['user1'], ENT_QUOTES, 'UTF-8');?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="password1"><?=$lang['edit']['password'];?></label>
-						<div class="col-sm-10">
-						<input type="password" class="form-control" name="password1" id="password1" value="<?=htmlspecialchars($result['password1'], ENT_QUOTES, 'UTF-8');?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="enc1"><?=$lang['edit']['encryption'];?>:</label>
-						<div class="col-sm-10">
-							<select id="enc1" name="enc1">
-								<option <?=($result['enc1'] == "TLS") ? "selected" : null;?>>TLS</option>
-								<option <?=($result['enc1'] == "SSL") ? "selected" : null;?>>SSL</option>
-								<option <?=($result['enc1'] == "PLAIN") ? "selected" : null;?>>PLAIN</option>
-							</select>
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="mins_interval"><?=$lang['edit']['mins_interval'];?></label>
-						<div class="col-sm-10">
-              <input type="number" class="form-control" name="mins_interval" min="10" max="3600" value="<?=htmlspecialchars($result['mins_interval'], ENT_QUOTES, 'UTF-8');?>" required>
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="subfolder2"><?=$lang['edit']['subfolder2'];?></label>
-						<div class="col-sm-10">
-						<input type="text" class="form-control" name="subfolder2" id="subfolder2" value="<?=htmlspecialchars($result['subfolder2'], ENT_QUOTES, 'UTF-8');?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="maxage"><?=$lang['edit']['maxage'];?></label>
-						<div class="col-sm-10">
-						<input type="number" class="form-control" name="maxage" id="maxage" value="<?=htmlspecialchars($result['maxage'], ENT_QUOTES, 'UTF-8');?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<label class="control-label col-sm-2" for="exclude"><?=$lang['edit']['exclude'];?></label>
-						<div class="col-sm-10">
-						<input type="text" class="form-control" name="exclude" id="exclude" value="<?=htmlspecialchars($result['exclude'], ENT_QUOTES, 'UTF-8');?>">
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-							<div class="checkbox">
-							<label><input type="checkbox" value="1" name="delete2duplicates" <?=($result['delete2duplicates']=="1") ? "checked" : "";?>> <?=$lang['edit']['delete2duplicates'];?></label>
-							</div>
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-							<div class="checkbox">
-							<label><input type="checkbox" value="1" name="delete1" <?=($result['delete1']=="1") ? "checked" : "";?>> <?=$lang['edit']['delete1'];?></label>
-							</div>
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-							<div class="checkbox">
-							<label><input type="checkbox" value="1" name="active" <?=($result['active']=="1") ? "checked" : "";?>> <?=$lang['edit']['active'];?></label>
-							</div>
-						</div>
-					</div>
-					<div class="form-group">
-						<div class="col-sm-offset-2 col-sm-10">
-              <button class="btn btn-success" id="edit_selected" data-id="editsyncjob" data-item="<?=htmlspecialchars($result['id']);?>" data-api-url='edit/syncjob' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
-						</div>
-					</div>
-				</form>
-			<?php
-			}
-			else {
-			?>
-				<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
-			<?php
-			}
-	}
-	else {
-	?>
-		<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
-	<?php
-	}
+          <div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
+        <?php
+        }
+      }
+  }
 }
 }
 else {
 else {
 ?>
 ?>

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

@@ -7,6 +7,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/modals/footer.php';
 <script src="/js/bootstrap-slider.min.js"></script>
 <script src="/js/bootstrap-slider.min.js"></script>
 <script src="/js/bootstrap-select.min.js"></script>
 <script src="/js/bootstrap-select.min.js"></script>
 <script src="/js/notifications.min.js"></script>
 <script src="/js/notifications.min.js"></script>
+<script src="/js/bootstrap-filestyle.min.js"></script>
 <script src="/js/u2f-api.js"></script>
 <script src="/js/u2f-api.js"></script>
 <script src="/js/api.js"></script>
 <script src="/js/api.js"></script>
 <script>
 <script>

+ 6 - 1
data/web/inc/functions.fail2ban.inc.php

@@ -17,7 +17,12 @@ function fail2ban($_action, $_data = null) {
           foreach ($wl as $key => $value) {
           foreach ($wl as $key => $value) {
             $tmp_data[] = $key;
             $tmp_data[] = $key;
           }
           }
-          $data['whitelist'] = implode(PHP_EOL, $tmp_data);
+          if (isset($tmp_data)) {
+            $data['whitelist'] = implode(PHP_EOL, $tmp_data);
+          }
+          else {
+            $data['whitelist'] = "";
+          }
         }
         }
         else {
         else {
           $data['whitelist'] = "";
           $data['whitelist'] = "";

+ 19 - 10
data/web/inc/functions.mailbox.inc.php

@@ -78,14 +78,21 @@ function mailbox($_action, $_type, $_data = null) {
               $username = $_data['username'];
               $username = $_data['username'];
             }
             }
           }
           }
-          else {
+          elseif ($_SESSION['mailcow_cc_role'] == "user") {
             $username = $_SESSION['mailcow_cc_username'];
             $username = $_SESSION['mailcow_cc_username'];
           }
           }
+          else {
+            $_SESSION['return'] = array(
+              'type' => 'danger',
+              'msg' => 'No user defined'
+            );
+            return false;
+          }
           $active  = intval($_data['active']);
           $active  = intval($_data['active']);
           $delete2duplicates = intval($_data['delete2duplicates']);
           $delete2duplicates = intval($_data['delete2duplicates']);
           $delete1  = intval($_data['delete1']);
           $delete1  = intval($_data['delete1']);
           $port1            = $_data['port1'];
           $port1            = $_data['port1'];
-          $host1            = $_data['host1'];
+          $host1            = strtolower($_data['host1']);
           $password1        = $_data['password1'];
           $password1        = $_data['password1'];
           $exclude          = $_data['exclude'];
           $exclude          = $_data['exclude'];
           $maxage           = $_data['maxage'];
           $maxage           = $_data['maxage'];
@@ -2060,7 +2067,11 @@ function mailbox($_action, $_type, $_data = null) {
             return false;
             return false;
           }
           }
           try {
           try {
-            $stmt = $pdo->prepare("SELECT * FROM `imapsync` WHERE id = :id");
+            $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 id = :id");
             $stmt->execute(array(':id' => $_data));
             $stmt->execute(array(':id' => $_data));
             $syncjobdetails = $stmt->fetch(PDO::FETCH_ASSOC);
             $syncjobdetails = $stmt->fetch(PDO::FETCH_ASSOC);
           }
           }
@@ -2086,14 +2097,12 @@ function mailbox($_action, $_type, $_data = null) {
             $_data = $_SESSION['mailcow_cc_username'];
             $_data = $_SESSION['mailcow_cc_username'];
           }
           }
           try {
           try {
-            $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 = $pdo->prepare("SELECT `id` FROM `imapsync` WHERE `user2` = :username");
             $stmt->execute(array(':username' => $_data));
             $stmt->execute(array(':username' => $_data));
-            $syncjobdata = $stmt->fetchAll(PDO::FETCH_ASSOC);
+            $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+            while($row = array_shift($rows)) {
+              $syncjobdata[] = $row['id'];
+            }
           }
           }
           catch(PDOException $e) {
           catch(PDOException $e) {
             $_SESSION['return'] = array(
             $_SESSION['return'] = array(

+ 2 - 2
data/web/inc/sessions.inc.php

@@ -15,7 +15,7 @@ elseif (isset($_SERVER['HTTPS'])) {
 else {
 else {
   $IS_HTTPS = false;
   $IS_HTTPS = false;
 }
 }
-session_set_cookie_params($SESSION_LIFETIME, '/', '', $IS_HTTPS, true);
+// session_set_cookie_params($SESSION_LIFETIME, '/', '', $IS_HTTPS, true);
 session_start();
 session_start();
 if (!isset($_SESSION['CSRF']['TOKEN'])) {
 if (!isset($_SESSION['CSRF']['TOKEN'])) {
   $_SESSION['CSRF']['TOKEN'] = bin2hex(random_bytes(32));
   $_SESSION['CSRF']['TOKEN'] = bin2hex(random_bytes(32));
@@ -27,7 +27,7 @@ if (!isset($_SESSION['SESS_REMOTE_UA'])) {
 }
 }
 
 
 // Update session cookie
 // Update session cookie
-setcookie(session_name() ,session_id(), time() + $SESSION_LIFETIME);
+// setcookie(session_name() ,session_id(), time() + $SESSION_LIFETIME);
 
 
 // Check session
 // Check session
 function session_check() {
 function session_check() {

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

@@ -54,6 +54,7 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admi
     }
     }
   }
   }
 }
 }
+
 if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "admin" || $_SESSION['mailcow_cc_role'] == "domainadmin")) {
 if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "admin" || $_SESSION['mailcow_cc_role'] == "domainadmin")) {
 	if (isset($_POST["set_tfa"])) {
 	if (isset($_POST["set_tfa"])) {
 		set_tfa($_POST);
 		set_tfa($_POST);

+ 9 - 5
data/web/js/admin.js

@@ -575,15 +575,19 @@ jQuery(function($){
 });
 });
 
 
 $(window).load(function(){
 $(window).load(function(){
-  width = $("#scrollbox").width();
+  initial_width = $("#sidebar-admin").width();
+  $("#scrollbox").css("width", initial_width);
   $(window).bind('scroll', function() {
   $(window).bind('scroll', function() {
     if ($(window).scrollTop() > 70) {
     if ($(window).scrollTop() > 70) {
       $('#scrollbox').addClass('scrollboxFixed');
       $('#scrollbox').addClass('scrollboxFixed');
-      $("#scrollbox").css("width", width);
     } else {
     } else {
-      width = $("#scrollbox").width();
       $('#scrollbox').removeClass('scrollboxFixed');
       $('#scrollbox').removeClass('scrollboxFixed');
-      $("#scrollbox").removeAttr("style");
     }
     }
   });
   });
-});
+});
+
+$(window).on('resize', function(){
+  on_resize_width = $("#sidebar-admin").width();
+  $("#scrollbox").removeAttr("style");
+  $("#scrollbox").css("width", on_resize_width);
+});

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

@@ -141,6 +141,7 @@ $(document).ready(function() {
         return false;
         return false;
       }
       }
     }
     }
+    // alert(JSON.stringify(api_attr));
     $.ajax({
     $.ajax({
       type: "POST",
       type: "POST",
       dataType: "json",
       dataType: "json",

ファイルの差分が大きいため隠しています
+ 0 - 0
data/web/js/bootstrap-filestyle.min.js


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

@@ -29,9 +29,35 @@ $(document).ready(function() {
     $('#password2').prop('type', 'text');
     $('#password2').prop('type', 'text');
     $('#password2').val(random_passwd);
     $('#password2').val(random_passwd);
   });
   });
-});
 
 
+  // 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>');
+  });
+});
 jQuery(function($){
 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];
+    });
+  }
+  // http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
+  function validateEmail(email) {
+    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
   // Calculation human readable file sizes
   function humanFileSize(bytes) {
   function humanFileSize(bytes) {
     if(Math.abs(bytes) < 1024) {
     if(Math.abs(bytes) < 1024) {
@@ -322,9 +348,55 @@ jQuery(function($){
     });
     });
   }
   }
 
 
+  function draw_sync_job_table() {
+    ft_syncjob_table = FooTable.init('#sync_job_table', {
+      "columns": [
+        {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
+        {"sorted": true,"name":"id","title":"ID","style":{"maxWidth":"60px","width":"60px","text-align":"center"}},
+        {"name":"user2","title":lang.owner},
+        {"name":"server_w_port","title":"Server","breakpoints":"xs"},
+        {"name":"mins_interval","title":lang.mins_interval,"breakpoints":"all"},
+        {"name":"last_run","title":lang.last_run,"breakpoints":"all"},
+        {"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/syncjobs/all',
+        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.user1 + '@' + 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>' +
+              '<a href="#" id="delete_selected" data-id="single-syncjob" data-api-url="delete/syncjob" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</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_domain_table();
   draw_domain_table();
   draw_mailbox_table();
   draw_mailbox_table();
   draw_resource_table();
   draw_resource_table();
   draw_alias_table();
   draw_alias_table();
   draw_aliasdomain_table();
   draw_aliasdomain_table();
+  draw_sync_job_table();
 });
 });

+ 5 - 5
data/web/js/user.js

@@ -2,8 +2,8 @@ $(document).ready(function() {
 
 
   // 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');
-  $(e.currentTarget).find('#logText').html('<pre style="background:none;font-size:11px;line-height:1.1;border:0px">' + logText + '</pre>');
+    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>');
   });
   });
 
 
 });
 });
@@ -73,7 +73,7 @@ jQuery(function($){
     ft_syncjob_table = FooTable.init('#sync_job_table', {
     ft_syncjob_table = FooTable.init('#sync_job_table', {
       "columns": [
       "columns": [
         {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
         {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
-        {"sorted": true,"name":"id","title":"ID"},
+        {"sorted": true,"name":"id","title":"ID","style":{"maxWidth":"60px","width":"60px","text-align":"center"}},
         {"name":"server_w_port","title":"Server"},
         {"name":"server_w_port","title":"Server"},
         {"name":"enc1","title":lang.encryption},
         {"name":"enc1","title":lang.encryption},
         {"name":"user1","title":lang.username},
         {"name":"user1","title":lang.username},
@@ -87,7 +87,7 @@ jQuery(function($){
       "empty": lang.empty,
       "empty": lang.empty,
       "rows": $.ajax({
       "rows": $.ajax({
         dataType: 'json',
         dataType: 'json',
-        url: '/api/v1/get/syncjobs',
+        url: '/api/v1/get/syncjobs/' + mailcow_cc_username,
         jsonp: false,
         jsonp: false,
         error: function () {
         error: function () {
           console.log('Cannot draw sync job table');
           console.log('Cannot draw sync job table');
@@ -96,7 +96,7 @@ jQuery(function($){
           $.each(data, function (i, item) {
           $.each(data, function (i, item) {
             item.log = '<a href="#logModal" data-toggle="modal" data-log-text="' + escapeHtml(item.returned_text) + '">Open logs</a>'
             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.exclude = '<code>' + item.exclude + '</code>'
-            item.server_w_port = item.host1 + ':' + item.port1;
+            item.server_w_port = item.user1 + '@' + item.host1 + ':' + item.port1;
             item.action = '<div class="btn-group">' +
             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>' +
               '<a href="/edit.php?syncjob=' + item.id + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
               '<a href="#" id="delete_selected" data-id="single-syncjob" data-api-url="delete/syncjob" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
               '<a href="#" id="delete_selected" data-id="single-syncjob" data-api-url="delete/syncjob" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +

+ 155 - 8
data/web/json_api.php

@@ -507,9 +507,35 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
               case "graph":
               case "graph":
                 switch ($extra) {
                 switch ($extra) {
                   case "hourly":
                   case "hourly":
-                    $data = file_get_contents('http://rspamd-mailcow:11334/graph?type=daily');
+                    $data = file_get_contents('http://rspamd-mailcow:11334/graph?type=hourly');
                     if (!empty($data)) {
                     if (!empty($data)) {
-                      echo $data;
+                      $data_array = json_decode($data, true);
+                      $rejected['label'] = "reject";
+                      foreach ($data_array[0] as $dataset) {
+                        $rejected['data'][] = $dataset;
+                      }
+                      $temp_reject['label'] = "temp_reject";
+                      foreach ($data_array[1] as $dataset) {
+                        $temp_reject['data'][] = $dataset;
+                      }
+                      $add_header['label'] = "add_header";
+                      foreach ($data_array[2] as $dataset) {
+                        $add_header['data'][] = $dataset;
+                      }
+                      $prob_spam['label'] = "prob_spam";
+                      foreach ($data_array[3] as $dataset) {
+                        $prob_spam['data'][] = $dataset;
+                      }
+                      $greylist['label'] = "greylist";
+                      foreach ($data_array[4] as $dataset) {
+                        $greylist['data'][] = $dataset;
+                      }
+                      $clean['label'] = "clean";
+                      $clean['pointStyle'] = "cross";
+                      foreach ($data_array[5] as $dataset) {
+                        $clean['data'][] = $dataset;
+                      }
+                      echo json_encode(array($rejected, $temp_reject, $add_header, $prob_spam, $greylist, $clean), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
                     }
                     }
                     elseif (!isset($data) || empty($data)) {
                     elseif (!isset($data) || empty($data)) {
                       echo '{}';
                       echo '{}';
@@ -518,25 +544,103 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
                   case "daily":
                   case "daily":
                     $data = file_get_contents('http://rspamd-mailcow:11334/graph?type=daily');
                     $data = file_get_contents('http://rspamd-mailcow:11334/graph?type=daily');
                     if (!empty($data)) {
                     if (!empty($data)) {
-                      echo $data;
+                      $data_array = json_decode($data, true);
+                      $rejected['label'] = "reject";
+                      foreach ($data_array[0] as $dataset) {
+                        $rejected['data'][] = $dataset;
+                      }
+                      $temp_reject['label'] = "temp_reject";
+                      foreach ($data_array[1] as $dataset) {
+                        $temp_reject['data'][] = $dataset;
+                      }
+                      $add_header['label'] = "add_header";
+                      foreach ($data_array[2] as $dataset) {
+                        $add_header['data'][] = $dataset;
+                      }
+                      $prob_spam['label'] = "prob_spam";
+                      foreach ($data_array[3] as $dataset) {
+                        $prob_spam['data'][] = $dataset;
+                      }
+                      $greylist['label'] = "greylist";
+                      foreach ($data_array[4] as $dataset) {
+                        $greylist['data'][] = $dataset;
+                      }
+                      $clean['label'] = "clean";
+                      $clean['pointStyle'] = "cross";
+                      foreach ($data_array[5] as $dataset) {
+                        $clean['data'][] = $dataset;
+                      }
+                      echo json_encode(array($rejected, $temp_reject, $add_header, $prob_spam, $greylist, $clean), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
                     }
                     }
                     elseif (!isset($data) || empty($data)) {
                     elseif (!isset($data) || empty($data)) {
                       echo '{}';
                       echo '{}';
                     }
                     }
                   break;
                   break;
                   case "weekly":
                   case "weekly":
-                    $data = file_get_contents('http://rspamd-mailcow:11334/graph?type=daily');
+                    $data = file_get_contents('http://rspamd-mailcow:11334/graph?type=weekly');
                     if (!empty($data)) {
                     if (!empty($data)) {
-                      echo $data;
+                      $data_array = json_decode($data, true);
+                      $rejected['label'] = "reject";
+                      foreach ($data_array[0] as $dataset) {
+                        $rejected['data'][] = $dataset;
+                      }
+                      $temp_reject['label'] = "temp_reject";
+                      foreach ($data_array[1] as $dataset) {
+                        $temp_reject['data'][] = $dataset;
+                      }
+                      $add_header['label'] = "add_header";
+                      foreach ($data_array[2] as $dataset) {
+                        $add_header['data'][] = $dataset;
+                      }
+                      $prob_spam['label'] = "prob_spam";
+                      foreach ($data_array[3] as $dataset) {
+                        $prob_spam['data'][] = $dataset;
+                      }
+                      $greylist['label'] = "greylist";
+                      foreach ($data_array[4] as $dataset) {
+                        $greylist['data'][] = $dataset;
+                      }
+                      $clean['label'] = "clean";
+                      $clean['pointStyle'] = "cross";
+                      foreach ($data_array[5] as $dataset) {
+                        $clean['data'][] = $dataset;
+                      }
+                      echo json_encode(array($rejected, $temp_reject, $add_header, $prob_spam, $greylist, $clean), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
                     }
                     }
                     elseif (!isset($data) || empty($data)) {
                     elseif (!isset($data) || empty($data)) {
                       echo '{}';
                       echo '{}';
                     }
                     }
                   break;
                   break;
                   case "monthly":
                   case "monthly":
-                    $data = file_get_contents('http://rspamd-mailcow:11334/graph?type=daily');
+                    $data = file_get_contents('http://rspamd-mailcow:11334/graph?type=monthly');
                     if (!empty($data)) {
                     if (!empty($data)) {
-                      echo $data;
+                      $data_array = json_decode($data, true);
+                      $rejected['label'] = "reject";
+                      foreach ($data_array[0] as $dataset) {
+                        $rejected['data'][] = $dataset;
+                      }
+                      $temp_reject['label'] = "temp_reject";
+                      foreach ($data_array[1] as $dataset) {
+                        $temp_reject['data'][] = $dataset;
+                      }
+                      $add_header['label'] = "add_header";
+                      foreach ($data_array[2] as $dataset) {
+                        $add_header['data'][] = $dataset;
+                      }
+                      $prob_spam['label'] = "prob_spam";
+                      foreach ($data_array[3] as $dataset) {
+                        $prob_spam['data'][] = $dataset;
+                      }
+                      $greylist['label'] = "greylist";
+                      foreach ($data_array[4] as $dataset) {
+                        $greylist['data'][] = $dataset;
+                      }
+                      $clean['label'] = "clean";
+                      $clean['pointStyle'] = "cross";
+                      foreach ($data_array[5] as $dataset) {
+                        $clean['data'][] = $dataset;
+                      }
+                      echo json_encode(array($rejected, $temp_reject, $add_header, $prob_spam, $greylist, $clean), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
                     }
                     }
                     elseif (!isset($data) || empty($data)) {
                     elseif (!isset($data) || empty($data)) {
                       echo '{}';
                       echo '{}';
@@ -734,8 +838,51 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
           break;
           break;
           case "syncjobs":
           case "syncjobs":
             switch ($object) {
             switch ($object) {
+              case "all":
+                $domains = mailbox('get', 'domains');
+                if (!empty($domains)) {
+                  foreach ($domains as $domain) {
+                    $mailboxes = mailbox('get', 'mailboxes', $domain);
+                    if (!empty($mailboxes)) {
+                      foreach ($mailboxes as $mailbox) {
+                        $syncjobs = mailbox('get', 'syncjobs', $mailbox);
+                        if (!empty($syncjobs)) {
+                          foreach ($syncjobs as $syncjob) {
+                            if ($details = mailbox('get', 'syncjob_details', $syncjob)) {
+                              $data[] = $details;
+                            }
+                            else {
+                              continue;
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                  if (!isset($data) || empty($data)) {
+                    echo '{}';
+                  }
+                  else {
+                    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
+                  }
+                }
+                else {
+                  echo '{}';
+                }
+              break;
+
               default:
               default:
-                $data = mailbox('get', 'syncjobs', $object);
+                $syncjobs = mailbox('get', 'syncjobs', $object);
+                if (!empty($syncjobs)) {
+                  foreach ($syncjobs as $syncjob) {
+                    if ($details = mailbox('get', 'syncjob_details', $syncjob)) {
+                      $data[] = $details;
+                    }
+                    else {
+                      continue;
+                    }
+                  }
+                }
                 if (!isset($data) || empty($data)) {
                 if (!isset($data) || empty($data)) {
                   echo '{}';
                   echo '{}';
                 }
                 }

+ 3 - 0
data/web/lang/lang.de.php

@@ -261,6 +261,9 @@ $lang['mailbox']['toggle_all'] = 'Alle';
 $lang['mailbox']['quick_actions'] = 'Aktionen';
 $lang['mailbox']['quick_actions'] = 'Aktionen';
 $lang['mailbox']['activate'] = 'Aktivieren';
 $lang['mailbox']['activate'] = 'Aktivieren';
 $lang['mailbox']['deactivate'] = 'Deaktivieren';
 $lang['mailbox']['deactivate'] = 'Deaktivieren';
+$lang['mailbox']['owner'] = 'Besitzer';
+$lang['mailbox']['mins_interval'] = 'Intervall (min)';
+$lang['mailbox']['last_run'] = 'Letzte Ausführung';
 
 
 $lang['info']['no_action'] = 'Keine Aktion anwendbar';
 $lang['info']['no_action'] = 'Keine Aktion anwendbar';
 $lang['delete']['title'] = 'Objekt entfernen';
 $lang['delete']['title'] = 'Objekt entfernen';

+ 3 - 0
data/web/lang/lang.en.php

@@ -264,6 +264,9 @@ $lang['mailbox']['toggle_all'] = 'Toggle all';
 $lang['mailbox']['quick_actions'] = 'Actions';
 $lang['mailbox']['quick_actions'] = 'Actions';
 $lang['mailbox']['activate'] = 'Activate';
 $lang['mailbox']['activate'] = 'Activate';
 $lang['mailbox']['deactivate'] = 'Deactivate';
 $lang['mailbox']['deactivate'] = 'Deactivate';
+$lang['mailbox']['owner'] = 'Owner';
+$lang['mailbox']['mins_interval'] = 'Interval (min)';
+$lang['mailbox']['last_run'] = 'Last run';
 
 
 $lang['info']['no_action'] = 'No action applicable';
 $lang['info']['no_action'] = 'No action applicable';
 
 

+ 24 - 0
data/web/mailbox.php

@@ -19,6 +19,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
         <li role="presentation"><a href="#tab-domain-aliases" aria-controls="tab-domain-aliases" role="tab" data-toggle="tab"><?=$lang['mailbox']['domain_aliases'];?></a></li>
         <li role="presentation"><a href="#tab-domain-aliases" aria-controls="tab-domain-aliases" role="tab" data-toggle="tab"><?=$lang['mailbox']['domain_aliases'];?></a></li>
       </ul>
       </ul>
     </li>
     </li>
+    <li role="presentation"><a href="#tab-syncjobs" aria-controls="tab-resources" role="tab" data-toggle="tab">Sync jobs</a></li>
   </ul>
   </ul>
 
 
 	<div class="row">
 	<div class="row">
@@ -147,6 +148,29 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
           </div>
           </div>
         </div>
         </div>
 
 
+        <div role="tabpanel" class="tab-pane" id="tab-syncjobs">
+          <div class="panel panel-default">
+            <div class="panel-heading">
+              <h3 class="panel-title">Sync jobs</h3>
+            </div>
+            <div class="table-responsive">
+              <table class="table table-striped" id="sync_job_table"></table>
+            </div>
+            <div class="mass-actions-mailbox">
+              <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-text="<?=$lang['user']['eas_reset'];?>?" data-id="syncjob" data-api-url='delete/syncjob' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+                </ul>
+                <a class="btn btn-sm btn-success" href="#" data-toggle="modal" data-target="#addSyncJobModalAdmin"><span class="glyphicon glyphicon-plus"></span> <?=$lang['user']['create_syncjob'];?></a>
+              </div>
+            </div>
+        </div>
+
       </div> <!-- /tab-content -->
       </div> <!-- /tab-content -->
     </div> <!-- /col-md-12 -->
     </div> <!-- /col-md-12 -->
   </div> <!-- /row -->
   </div> <!-- /row -->

+ 130 - 2
data/web/modals/mailbox.php

@@ -31,7 +31,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
               ?>
               ?>
               </select>
               </select>
             </div>
             </div>
-          </div> 
+          </div>
           <div class="form-group">
           <div class="form-group">
             <label class="control-label col-sm-2" for="name"><?=$lang['add']['full_name'];?></label>
             <label class="control-label col-sm-2" for="name"><?=$lang['add']['full_name'];?></label>
             <div class="col-sm-10">
             <div class="col-sm-10">
@@ -301,4 +301,132 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
-</div><!-- add domain alias modal -->
+</div><!-- add domain alias modal -->
+<!-- add sync job modal -->
+<div class="modal fade" id="addSyncJobModalAdmin" 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"><?=$lang['add']['syncjob'];?></h3>
+      </div>
+      <div class="modal-body">
+        <p><?=$lang['add']['syncjob_hint'];?></p>
+				<form class="form-horizontal" role="form" data-id="add_syncjob">
+          <div class="form-group">
+            <label class="control-label col-sm-2" for="username"><?=$lang['add']['username'];?>:</label>
+            <div class="col-sm-10">
+              <select id="addSelectUsername" name="username" id="username" required>
+              <?php
+              $domains = mailbox('get', 'domains');
+              if (!empty($domains)) {
+                foreach ($domains as $domain) {
+                  $mailboxes = mailbox('get', 'mailboxes', $domain);
+                  foreach ($mailboxes as $mailbox) {
+                    echo "<option>".htmlspecialchars($mailbox)."</option>";
+                  }
+                }
+              }
+              ?>
+              </select>
+            </div>
+          </div> 
+					<div class="form-group">
+						<label class="control-label col-sm-2" for="host1"><?=$lang['add']['hostname'];?></label>
+						<div class="col-sm-10">
+						<input type="text" class="form-control" name="host1" id="host1" required>
+						</div>
+					</div>
+					<div class="form-group">
+						<label class="control-label col-sm-2" for="port1"><?=$lang['add']['port'];?></label>
+						<div class="col-sm-10">
+						<input type="number" class="form-control" name="port1" id="port1" min="1" max="65535" value="143" required>
+						</div>
+					</div>
+					<div class="form-group">
+						<label class="control-label col-sm-2" for="user1"><?=$lang['add']['username'];?></label>
+						<div class="col-sm-10">
+						<input type="text" class="form-control" name="user1" id="user1" required>
+						</div>
+					</div>
+					<div class="form-group">
+						<label class="control-label col-sm-2" for="password1"><?=$lang['add']['password'];?></label>
+						<div class="col-sm-10">
+						<input type="password" class="form-control" name="password1" id="password1" required>
+						</div>
+					</div>
+					<div class="form-group">
+						<label class="control-label col-sm-2" for="enc1"><?=$lang['add']['enc_method'];?></label>
+						<div class="col-sm-10">
+							<select name="enc1" id="enc1" title="<?=$lang['add']['select'];?>" required>
+                <option selected>TLS</option>
+                <option>SSL</option>
+                <option>PLAIN</option>
+							</select>
+						</div>
+					</div>
+					<div class="form-group">
+						<label class="control-label col-sm-2" for="mins_interval"><?=$lang['add']['mins_interval'];?></label>
+						<div class="col-sm-10">
+              <input type="number" class="form-control" name="mins_interval" min="10" max="3600" value="20" required>
+						</div>
+					</div>
+					<div class="form-group">
+						<label class="control-label col-sm-2" for="subfolder2"><?=$lang['edit']['subfolder2'];?></label>
+						<div class="col-sm-10">
+						<input type="text" class="form-control" name="subfolder2" id="subfolder2" value="External">
+						</div>
+					</div>
+					<div class="form-group">
+						<label class="control-label col-sm-2" for="maxage"><?=$lang['edit']['maxage'];?></label>
+						<div class="col-sm-10">
+						<input type="number" class="form-control" name="maxage" id="maxage" min="0" max="32000" value="0">
+						</div>
+					</div>
+					<div class="form-group">
+						<label class="control-label col-sm-2" for="exclude"><?=$lang['add']['exclude'];?></label>
+						<div class="col-sm-10">
+						<input type="text" class="form-control" name="exclude" id="exclude" value="(?i)spam|(?i)junk">
+						</div>
+					</div>
+					<div class="form-group">
+						<div class="col-sm-offset-2 col-sm-10">
+							<div class="checkbox">
+							<label><input type="checkbox" value="1" name="delete2duplicates" checked> <?=$lang['add']['delete2duplicates'];?></label>
+							</div>
+						</div>
+					</div>
+					<div class="form-group">
+						<div class="col-sm-offset-2 col-sm-10">
+							<div class="checkbox">
+							<label><input type="checkbox" value="1" name="delete1"> <?=$lang['add']['delete1'];?></label>
+							</div>
+						</div>
+					</div>
+					<div class="form-group">
+						<div class="col-sm-offset-2 col-sm-10">
+							<div class="checkbox">
+							<label><input type="checkbox" value="1" name="active" checked> <?=$lang['add']['active'];?></label>
+							</div>
+						</div>
+					</div>
+					<div class="form-group">
+						<div class="col-sm-offset-2 col-sm-10">
+              <button class="btn btn-default" id="add_item" data-id="add_syncjob" data-api-url='add/syncjob' data-api-attr='{}' href="#"><?=$lang['admin']['add'];?></button>
+						</div>
+					</div>
+				</form>
+      </div>
+    </div>
+  </div>
+</div><!-- add sync job modal -->
+<!-- log modal -->
+<div class="modal fade" id="logModal" tabindex="-1" role="dialog" aria-labelledby="logTextLabel">
+  <div class="modal-dialog" style="width:90%" role="document">
+    <div class="modal-content">
+      <div class="modal-body">
+        <span id="logText"></span>
+      </div>
+    </div>
+  </div>
+</div><!-- log modal -->

+ 46 - 0
data/web/modals/user.php

@@ -104,3 +104,49 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
     </div>
     </div>
   </div>
   </div>
 </div><!-- add sync job modal -->
 </div><!-- add sync job modal -->
+<!-- log modal -->
+<div class="modal fade" id="logModal" tabindex="-1" role="dialog" aria-labelledby="logTextLabel">
+  <div class="modal-dialog" style="width:90%" role="document">
+    <div class="modal-content">
+      <div class="modal-body">
+        <span id="logText"></span>
+      </div>
+    </div>
+  </div>
+</div><!-- log modal -->
+<!-- pw change modal -->
+<div class="modal fade" id="pwChangeModal" tabindex="-1" role="dialog" aria-labelledby="pwChangeModalLabel">
+  <div class="modal-dialog" role="document">
+    <div class="modal-content">
+      <div class="modal-body">
+        <form class="form-horizontal" data-id="pwchange" role="form" method="post" autocomplete="off">
+          <div class="form-group">
+            <label class="control-label col-sm-3" for="user_new_pass"><?=$lang['user']['new_password'];?></label>
+            <div class="col-sm-5">
+            <input type="password" class="form-control" name="user_new_pass" id="user_new_pass" autocomplete="off" required>
+            </div>
+          </div>
+          <div class="form-group">
+            <label class="control-label col-sm-3" for="user_new_pass2"><?=$lang['user']['new_password_repeat'];?></label>
+            <div class="col-sm-5">
+            <input type="password" class="form-control" name="user_new_pass2" id="user_new_pass2" autocomplete="off" required>
+            <p class="help-block"><?=$lang['user']['new_password_description'];?></p>
+            </div>
+          </div>
+          <hr>
+          <div class="form-group">
+            <label class="control-label col-sm-3" for="user_old_pass"><?=$lang['user']['password_now'];?></label>
+            <div class="col-sm-5">
+            <input type="password" class="form-control" name="user_old_pass" id="user_old_pass" autocomplete="off" required>
+            </div>
+          </div>
+          <div class="form-group">
+            <div class="col-sm-offset-3 col-sm-9">
+              <button class="btn btn-default" id="edit_selected" data-id="pwchange" data-item="null" data-api-url='edit/self' data-api-attr='{}' href="#"><?=$lang['user']['change_password'];?></button>
+            </div>
+          </div>
+        </form>
+      </div>
+    </div>
+  </div>
+</div><!-- pw change modal -->

+ 6 - 58
data/web/user.php

@@ -51,7 +51,7 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'doma
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
-</div>
+  </div>
 <?php
 <?php
 }
 }
 elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') {
 elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') {
@@ -256,7 +256,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
         <button type="button" class="btn btn-sm btn-success" id="edit_selected"
         <button type="button" class="btn btn-sm btn-success" id="edit_selected"
           data-item="<?= $username; ?>"
           data-item="<?= $username; ?>"
           data-id="spam_score"
           data-id="spam_score"
-          data-api-url='edit/spam_score'
+          data-api-url='edit/spam-score'
           data-api-attr='{}'><?=$lang['user']['save_changes'];?></button>
           data-api-attr='{}'><?=$lang['user']['save_changes'];?></button>
 				</div>
 				</div>
 			</div>
 			</div>
@@ -331,65 +331,12 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
     </div>
     </div>
 		</div>
 		</div>
 	</div>
 	</div>
-</div>
-
-<?php
-}
-if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "user" || $_SESSION['mailcow_cc_role'] == "domainadmin")) {
-
-  /*
-  / USER OR DOMAIN ADMIN
-  */
-
-?>
-<div class="modal fade" id="logModal" tabindex="-1" role="dialog" aria-labelledby="logTextLabel">
-  <div class="modal-dialog" style="width:90%" role="document">
-    <div class="modal-content">
-      <div class="modal-body">
-        <span id="logText"></span>
-      </div>
-    </div>
-  </div>
-</div>
 
 
+</div><!-- /container -->
 <div style="margin-bottom:200px;"></div>
 <div style="margin-bottom:200px;"></div>
-<div class="modal fade" id="pwChangeModal" tabindex="-1" role="dialog" aria-labelledby="pwChangeModalLabel">
-  <div class="modal-dialog" role="document">
-    <div class="modal-content">
-      <div class="modal-body">
-        <form class="form-horizontal" data-id="pwchange" role="form" method="post" autocomplete="off">
-          <div class="form-group">
-            <label class="control-label col-sm-3" for="user_new_pass"><?=$lang['user']['new_password'];?></label>
-            <div class="col-sm-5">
-            <input type="password" class="form-control" name="user_new_pass" id="user_new_pass" autocomplete="off" required>
-            </div>
-          </div>
-          <div class="form-group">
-            <label class="control-label col-sm-3" for="user_new_pass2"><?=$lang['user']['new_password_repeat'];?></label>
-            <div class="col-sm-5">
-            <input type="password" class="form-control" name="user_new_pass2" id="user_new_pass2" autocomplete="off" required>
-            <p class="help-block"><?=$lang['user']['new_password_description'];?></p>
-            </div>
-          </div>
-          <hr>
-          <div class="form-group">
-            <label class="control-label col-sm-3" for="user_old_pass"><?=$lang['user']['password_now'];?></label>
-            <div class="col-sm-5">
-            <input type="password" class="form-control" name="user_old_pass" id="user_old_pass" autocomplete="off" required>
-            </div>
-          </div>
-          <div class="form-group">
-            <div class="col-sm-offset-3 col-sm-9">
-              <button class="btn btn-default" id="edit_selected" data-id="pwchange" data-item="null" data-api-url='edit/self' data-api-attr='{}' href="#"><?=$lang['user']['change_password'];?></button>
-            </div>
-          </div>
-        </form>
-      </div>
-    </div>
-  </div>
-</div>
-</div> <!-- /container -->
 <?php
 <?php
+}
+if (isset($_SESSION['mailcow_cc_role'])) {
 require_once $_SERVER['DOCUMENT_ROOT'] . '/modals/user.php';
 require_once $_SERVER['DOCUMENT_ROOT'] . '/modals/user.php';
 ?>
 ?>
 <script type='text/javascript'>
 <script type='text/javascript'>
@@ -397,6 +344,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/modals/user.php';
 $lang_user = json_encode($lang['user']);
 $lang_user = json_encode($lang['user']);
 echo "var lang = ". $lang_user . ";\n";
 echo "var lang = ". $lang_user . ";\n";
 echo "var csrf_token = '". $_SESSION['CSRF']['TOKEN'] . "';\n";
 echo "var csrf_token = '". $_SESSION['CSRF']['TOKEN'] . "';\n";
+echo "var mailcow_cc_username = '". $_SESSION['mailcow_cc_username'] . "';\n";
 echo "var pagination_size = '". $PAGINATION_SIZE . "';\n";
 echo "var pagination_size = '". $PAGINATION_SIZE . "';\n";
 ?>
 ?>
 </script>
 </script>

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません