Browse Source

Cleanup, cleanup and cleanup, much better sender acl handling, imapsync jobs, login as mailbox user X

andryyy 8 years ago
parent
commit
365abdda01

+ 88 - 64
data/web/admin.php

@@ -74,63 +74,36 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
 						</thead>
 						<tbody>
 							<?php
-							try {
-								$stmt = $pdo->query("SELECT DISTINCT
-									`username`, 
-									CASE WHEN `active`='1' THEN '".$lang['admin']['yes']."' ELSE '".$lang['admin']['no']."' END AS `active`
-										FROM `domain_admins` 
-											WHERE `username` IN (
-												SELECT `username` FROM `admin`
-													WHERE `superadmin`!='1'
-											)");
-								$rows_username = $stmt->fetchAll(PDO::FETCH_ASSOC);
-							}
-							catch(PDOException $e) {
-								$_SESSION['return'] = array(
-									'type' => 'danger',
-									'msg' => 'MySQL: '.$e
-								);
-							}
-							if(!empty($rows_username)):
-							while ($row_user_state = array_shift($rows_username)):
+              foreach (get_domain_admins() as $domain_admin) {
+                $da_data = get_domain_admin_details($domain_admin); 
+                if (!empty($da_data)):
 							?>
 							<tr id="data">
-								<td><?=htmlspecialchars(strtolower($row_user_state['username']));?></td>
+								<td><?=htmlspecialchars(strtolower($domain_admin));?></td>
 								<td>
 								<?php
-								try {
-									$stmt = $pdo->prepare("SELECT `domain` FROM `domain_admins` WHERE `username` = :username");
-									$stmt->execute(array('username' => $row_user_state['username']));
-									$rows_domain = $stmt->fetchAll(PDO::FETCH_ASSOC);
-								}
-								catch(PDOException $e) {
-									$_SESSION['return'] = array(
-										'type' => 'danger',
-										'msg' => 'MySQL: '.$e
-									);
-								}
-								while ($row_domain = array_shift($rows_domain)) {
-									echo htmlspecialchars($row_domain['domain']).'<br />';
+								foreach ($da_data['selected_domains'] as $domain) {
+									echo htmlspecialchars($domain).'<br />';
 								}
 								?>
 								</td>
-								<td><?=$row_user_state['active'];?></td>
+								<td><?=$da_data['active'];?></td>
 								<td style="text-align: right;">
 									<div class="btn-group">
-										<a href="edit.php?domainadmin=<?=$row_user_state['username'];?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['admin']['edit'];?></a>
-										<a href="delete.php?domainadmin=<?=$row_user_state['username'];?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['admin']['remove'];?></a>
+										<a href="edit.php?domainadmin=<?=$domain_admin;?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['admin']['edit'];?></a>
+										<a href="delete.php?domainadmin=<?=$domain_admin;?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['admin']['remove'];?></a>
 									</div>
 								</td>
 								</td>
 							</tr>
 
 							<?php
-							endwhile;
 							else:
 							?>
 								<tr id="no-data"><td colspan="4" style="text-align: center; font-style: italic;"><?=$lang['admin']['no_record'];?></td></tr>
 							<?php
 							endif;
+              }
 							?>
 						</tbody>
 					</table>
@@ -204,41 +177,93 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
 <div class="panel-heading"><?=$lang['admin']['dkim_keys'];?></div>
 <div id="collapseDKIM" class="panel-collapse">
 <div class="panel-body">
+  <p style="margin-bottom:40px"><?=$lang['admin']['dkim_key_hint'];?></p>
 	<?php
-	$dnstxt_folder = scandir($GLOBALS["MC_DKIM_TXTS"]);
-	$dnstxt_files = array_diff($dnstxt_folder, array('.', '..'));
-	foreach($dnstxt_files as $file) {
-		$pubKey = file_get_contents($GLOBALS["MC_DKIM_TXTS"]."/".$file);
-		$domain = substr($file, 0, -5);
-	?>
-		<div class="row">
-			<div class="col-xs-2">
-				<p>Domain: <strong><?=htmlspecialchars($domain);?></strong> (dkim._domainkey)</p>
-			</div>
-			<div class="col-xs-9">
-				<pre>v=DKIM1;k=rsa;t=s;s=email;p=<?=$pubKey;?></pre>
-			</div>
-			<div class="col-xs-1">
-				<form class="form-inline" role="form" method="post">
-				<a href="#" onclick="$(this).closest('form').submit()"><span class="glyphicon glyphicon-remove-circle"></span></a>
-				<input type="hidden" name="delete_dkim_record" value="<?=htmlspecialchars($file);?>">
-                <input type="hidden" name="dkim[domain]" value="<?=$domain;?>">
-				</form>
-			</div>
-		</div>
-	<?php
+	foreach(mailbox_get_domains() as $domain) {
+    if ($pubkey = dkim_table('get', $domain)) {
+    ?>
+      <div class="row">
+        <div class="col-xs-3">
+          <p>Domain: <strong><?=htmlspecialchars($domain);?></strong><br /><span class="label label-success"><?=$lang['admin']['dkim_key_valid'];?></span></p>
+        </div>
+        <div class="col-xs-8">
+          <pre><?=$pubkey;?></pre>
+        </div>
+        <div class="col-xs-1">
+          <form class="form-inline" method="post">
+            <input type="hidden" name="dkim[domain]" value="<?=$domain;?>">
+            <input type="hidden" name="delete_dkim_record" value="1">
+            <a href="#" onclick="$(this).closest('form').submit()"><span class="glyphicon glyphicon-remove-circle"></span></a>
+          </form>
+        </div>
+      </div>
+    <?php
+    }
+    foreach(mailbox_get_alias_domains($domain) as $alias_domain) {
+      if ($pubkey = dkim_table('get', $alias_domain)) {
+      ?>
+        <div class="row">
+          <div class="col-xs-offset-1 col-xs-2">
+            <p><small>↳ Alias-Domain: <strong><?=htmlspecialchars($alias_domain);?></strong><br /></small><span class="label label-success"><?=$lang['admin']['dkim_key_valid'];?></span></p>
+          </div>
+          <div class="col-xs-8">
+            <pre><?=$pubkey;?></pre>
+          </div>
+          <div class="col-xs-1">
+            <form class="form-inline" method="post">
+              <input type="hidden" name="dkim[domain]" value="<?=$alias_domain;?>">
+              <input type="hidden" name="delete_dkim_record" value="1">
+              <a href="#" onclick="$(this).closest('form').submit()"><span class="glyphicon glyphicon-remove-circle"></span></a>
+            </form>
+          </div>
+        </div>
+      <?php
+      }
+    }
 	}
+  ?><hr><?php
+  foreach(dkim_table('keys-without-domain', null) as $key_wo_domain) {
+    if ($pubkey = dkim_table('get', $key_wo_domain)) {
+    ?>
+      <div class="row">
+        <div class="col-xs-3">
+          <p>Domain: <strong><?=htmlspecialchars($key_wo_domain);?></strong><br /><span class="label label-warning"><?=$lang['admin']['dkim_key_unused'];?></span></p>
+        </div>
+          <div class="col-xs-8">
+            <pre><?=$pubkey;?></pre>
+          </div>
+          <div class="col-xs-1">
+            <form class="form-inline" method="post">
+              <input type="hidden" name="dkim[domain]" value="<?=$key_wo_domain;?>">
+              <input type="hidden" name="delete_dkim_record" value="1">
+              <a href="#" onclick="$(this).closest('form').submit()"><span class="glyphicon glyphicon-remove-circle"></span></a>
+            </form>
+          </div>
+      </div>
+    <?php
+    }
+  }
+  ?><hr><?php
+  foreach(dkim_table('domains-without-key', null) as $domain_wo_key) {
+  ?>
+    <div class="row">
+      <div class="col-xs-12">
+        <p>(Alias-)Domain: <strong><?=htmlspecialchars($domain_wo_key);?></strong><br /><span class="label label-danger"><?=$lang['admin']['dkim_key_missing'];?></span></p>
+      </div>
+    </div>
+  <?php
+  }
 	?>
-	<legend><?=$lang['admin']['dkim_add_key'];?></legend>
+	<legend style="margin-top:40px"><?=$lang['admin']['dkim_add_key'];?></legend>
 	<form class="form-inline" role="form" method="post">
 		<div class="form-group">
 			<label for="dkim_domain">Domain</label>
 			<input class="form-control" id="dkim_domain" name="dkim[domain]" placeholder="example.org" required>
 		</div>
 		<div class="form-group">
-			<select class="form-control" id="dkim_key_size" name="dkim[key_size]" title="<?=$lang['admin']['dkim_key_length'];?>" required>
-				<option>1024</option>
-				<option>2048</option>
+			<select data-width="200px" class="form-control" id="dkim_key_size" name="dkim[key_size]" title="<?=$lang['admin']['dkim_key_length'];?>" required>
+				<option data-subtext="bits">1024</option>
+				<option data-subtext="bits">2048</option>
 			</select>
 		</div>
 		<button type="submit" name="add_dkim_record" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> <?=$lang['admin']['add'];?></button>
@@ -246,7 +271,6 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
 </div>
 </div>
 </div>
-
 </div> <!-- /container -->
 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js" integrity="sha384-YWP9O4NjmcGo4oEJFXvvYSEzuHIvey+LbXkBNJ1Kd0yfugEZN9NCQNpRYBVC1RvA" crossorigin="anonymous"></script>

+ 9 - 31
data/web/delete.php

@@ -66,20 +66,9 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 			isset($_GET["aliasdomain"]) &&
 			is_valid_domain_name($_GET["aliasdomain"]) && 
 			!empty($_GET["aliasdomain"])) {
-				$alias_domain = strtolower(trim($_GET["aliasdomain"]));
-				try {
-					$stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
-							WHERE `alias_domain`= :alias_domain");
-					$stmt->execute(array(':alias_domain' => $alias_domain));
-					$DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
-				}
-				catch(PDOException $e) {
-					$_SESSION['return'] = array(
-						'type' => 'danger',
-						'msg' => 'MySQL: '.$e
-					);
-				}
-				if (hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $DomainData['target_domain'])) {
+        $alias_domain = $_GET["aliasdomain"];
+        $result = mailbox_get_alias_domain_details($alias_domain);
+				if (!empty($result)) {
 				?>
 					<div class="alert alert-warning" role="alert"><?=sprintf($lang['delete']['remove_domainalias_warning'], htmlspecialchars($_GET["aliasdomain"]));?></div>
 					<form class="form-horizontal" role="form" method="post" action="/mailbox.php">
@@ -102,7 +91,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 		elseif (isset($_GET["domainadmin"]) &&
 			ctype_alnum(str_replace(array('_', '.', '-'), '', $_GET["domainadmin"])) &&
 			!empty($_GET["domainadmin"]) &&
-			$_SESSION['mailcow_cc_role'] == "admin") {
+        $_SESSION['mailcow_cc_role'] == "admin") {
 				$domain_admin = $_GET["domainadmin"];
 				?>
 				<div class="alert alert-warning" role="alert"><?=sprintf($lang['delete']['remove_domainadmin_warning'], htmlspecialchars($_GET["domainadmin"]));?></div>
@@ -121,8 +110,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 			filter_var($_GET["mailbox"], FILTER_VALIDATE_EMAIL) &&
 			!empty($_GET["mailbox"])) {
 				$mailbox = $_GET["mailbox"];
-				$domain = substr(strrchr($mailbox, "@"), 1);
-				if (hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+				if (hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $mailbox)) {
 				?>
 					<div class="alert alert-warning" role="alert"><?=sprintf($lang['delete']['remove_mailbox_warning'], htmlspecialchars($_GET["mailbox"]));?></div>
 					<p><?=$lang['delete']['remove_mailbox_details'];?></p>
@@ -153,21 +141,11 @@ elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] ==
 		if (isset($_GET["syncjob"]) &&
 			is_numeric($_GET["syncjob"]) &&
       filter_var($_SESSION['mailcow_cc_username'], FILTER_VALIDATE_EMAIL)) {
-        try {
-          $stmt = $pdo->prepare("SELECT `user2` FROM `imapsync`
-              WHERE `id` = :id AND user2 = :user2");
-          $stmt->execute(array(':id' => $_GET["syncjob"], ':user2' => $_SESSION['mailcow_cc_username']));
-          $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
-        }
-        catch(PDOException $e) {
-          $_SESSION['return'] = array(
-            'type' => 'danger',
-            'msg' => 'MySQL: '.$e
-          );
-        }
-				if ($num_results != 0 && !empty($num_results)) {
+        $id = $_GET["syncjob"];
+        $result = get_syncjob_details($id);
+        if (!empty($result)) {
 				?>
-					<div class="alert alert-warning" role="alert"><?=sprintf($lang['delete']['remove_syncjob_warning'], htmlspecialchars($_SESSION['mailcow_cc_username']));?></div>
+					<div class="alert alert-warning" role="alert"><?=sprintf($lang['delete']['remove_syncjob_warning'], htmlspecialchars($result['user2']));?></div>
 					<p><?=$lang['delete']['remove_syncjob_details'];?></p>
 					<form class="form-horizontal" role="form" method="post" action="/user.php">
 					<input type="hidden" name="username" value="<?=htmlspecialchars($mailbox);?>">

+ 218 - 252
data/web/edit.php

@@ -20,34 +20,8 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 		if (isset($_GET["alias"]) &&
 			!empty($_GET["alias"])) {
 				$alias = $_GET["alias"];
-				$domain = substr(strrchr($alias, "@"), 1);
-				try {
-					$stmt = $pdo->prepare("SELECT * FROM `alias`
-						WHERE `address`= :address 
-						AND `goto` != :goto
-						AND (
-							`domain` IN (
-								SELECT `domain` FROM `domain_admins`
-									WHERE `active`='1'
-									AND `username`= :username
-							)
-							OR 'admin'= :admin
-						)");
-					$stmt->execute(array(
-						':address' => $alias,
-						':goto' => $alias,
-						':username' => $_SESSION['mailcow_cc_username'],
-						':admin' => $_SESSION['mailcow_cc_role']
-					));
-					$result = $stmt->fetch(PDO::FETCH_ASSOC);
-				}
-				catch(PDOException $e) {
-					$_SESSION['return'] = array(
-						'type' => 'danger',
-						'msg' => 'MySQL: '.$e
-					);
-				}
-				if ($result !== false) {
+        $result = mailbox_get_alias_details($alias);
+				if (!empty($result)) {
 				?>
 					<h4><?=$lang['edit']['alias'];?></h4>
 					<br />
@@ -62,7 +36,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 						<div class="form-group">
 							<div class="col-sm-offset-2 col-sm-10">
 								<div class="checkbox">
-								<label><input type="checkbox" name="active" <?php if (isset($result['active']) && $result['active']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
+								<label><input type="checkbox" name="active" <?php if (isset($result['active_int']) && $result['active_int']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
 								</div>
 							</div>
 						</div>
@@ -86,68 +60,34 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 			$_GET["domainadmin"] != 'admin' &&
 			$_SESSION['mailcow_cc_role'] == "admin") {
 				$domain_admin = $_GET["domainadmin"];
-				try {
-					$stmt = $pdo->prepare("SELECT * FROM `domain_admins` WHERE `username`= :domain_admin");
-					$stmt->execute(array(
-						':domain_admin' => $domain_admin
-					));
-					$result = $stmt->fetch(PDO::FETCH_ASSOC);
-				}
-				catch(PDOException $e) {
-					$_SESSION['return'] = array(
-						'type' => 'danger',
-						'msg' => 'MySQL: '.$e
-					);
-				}
-				if ($result !== false) {
+        $result = get_domain_admin_details($domain_admin);
+				if (!empty($result)) {
 				?>
 				<h4><?=$lang['edit']['domain_admin'];?></h4>
 				<br />
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
 				<input type="hidden" name="username" value="<?=htmlspecialchars($domain_admin);?>">
+					<div class="form-group">
+						<label class="control-label col-sm-2" for="username"><?=$lang['edit']['username'];?></label>
+						<div class="col-sm-10">
+              <input class="form-control" type="text" disabled value="<?=htmlspecialchars($domain_admin);?>" />
+						</div>
+					</div>
 					<div class="form-group">
 						<label class="control-label col-sm-2" for="domain"><?=$lang['edit']['domains'];?></label>
 						<div class="col-sm-10">
 							<select id="domain" name="domain[]" multiple>
 							<?php
-							try {
-								$stmt = $pdo->prepare("SELECT `domain` FROM `domain`
-									WHERE `domain` IN (
-										SELECT `domain` FROM `domain_admins`
-											WHERE `username`= :domain_admin)");
-								$stmt->execute(array(':domain_admin' => $domain_admin));
-								$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
-							}
-							catch(PDOException $e) {
-								$_SESSION['return'] = array(
-									'type' => 'danger',
-									'msg' => 'MySQL: '.$e
-								);
-							}
-							while ($row_selected = array_shift($rows)):
+							foreach ($result['selected_domains'] as $domain):
 							?>
-								<option selected><?=htmlspecialchars($row_selected['domain']);?></option>
+								<option selected><?=htmlspecialchars($domain);?></option>
 							<?php
-							endwhile;
-							try {
-								$stmt = $pdo->prepare("SELECT `domain` FROM `domain`
-									WHERE `domain` NOT IN (
-										SELECT `domain` FROM `domain_admins`
-											WHERE `username`= :domain_admin)");
-								$stmt->execute(array(':domain_admin' => $domain_admin));
-								$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
-							}
-							catch(PDOException $e) {
-								$_SESSION['return'] = array(
-									'type' => 'danger',
-									'msg' => 'MySQL: '.$e
-								);
-							}
-							while ($row_unselected = array_shift($rows)):
+							endforeach;
+							foreach ($result['unselected_domains'] as $domain):
 							?>
-								<option><?=htmlspecialchars($row_unselected['domain']);?></option>
+								<option><?=htmlspecialchars($domain);?></option>
 							<?php
-							endwhile;
+							endforeach;
 							?>
 							</select>
 						</div>
@@ -167,7 +107,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="active" <?php if (isset($result['active']) && $result['active']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
+							<label><input type="checkbox" name="active" <?php if (isset($result['active_int']) && $result['active_int']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
 							</div>
 						</div>
 					</div>
@@ -189,29 +129,8 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 		is_valid_domain_name($_GET["domain"]) &&
 		!empty($_GET["domain"])) {
 			$domain = $_GET["domain"];
-			try {
-				$stmt = $pdo->prepare("SELECT * FROM `domain` WHERE `domain`='".$domain."'
-				AND (
-					`domain` IN (
-						SELECT `domain` from `domain_admins`
-							WHERE `active`='1'
-							AND `username` = :username
-					)
-					OR 'admin'= :admin
-				)");
-				$stmt->execute(array(
-					':username' => $_SESSION['mailcow_cc_username'],
-					':admin' => $_SESSION['mailcow_cc_role']
-				));
-				$result = $stmt->fetch(PDO::FETCH_ASSOC);
-			}
-			catch(PDOException $e) {
-				$_SESSION['return'] = array(
-					'type' => 'danger',
-					'msg' => 'MySQL: '.$e
-				);
-			}
-			if ($result !== false) {
+      $result = mailbox_get_domain_details($domain);
+			if (!empty($result)) {
 			?>
 				<h4><?=$lang['edit']['domain'];?></h4>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
@@ -228,34 +147,34 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<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['aliases']);?>">
+							<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['mailboxes']);?>">
+							<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['maxquota']);?>">
+							<input type="number" class="form-control" name="maxquota" id="maxquota" value="<?=intval($result['max_quota_for_mbox_mib']);?>">
 						</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['quota']);?>">
+							<input type="number" class="form-control" name="quota" id="quota" value="<?=intval($result['max_quota_for_domain_mib']);?>">
 						</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" name="backupmx" <?php if (isset($result['backupmx']) && $result['backupmx']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['relay_domain'];?></label>
+								<label><input type="checkbox" name="backupmx" <?=(isset($result['backupmx_int']) && $result['backupmx_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['relay_domain'];?></label>
 								<br />
-								<label><input type="checkbox" name="relay_all_recipients" <?php if (isset($result['relay_all_recipients']) && $result['relay_all_recipients']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['relay_all'];?></label>
+								<label><input type="checkbox" name="relay_all_recipients" <?=(isset($result['relay_all_recipients']) && $result['relay_all_recipients']=="1") ? "checked" : null;?>> <?=$lang['edit']['relay_all'];?></label>
 								<p><?=$lang['edit']['relay_all_info'];?></p>
 							</div>
 						</div>
@@ -266,7 +185,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-								<label><input type="checkbox" name="active" <?php if (isset($result['active']) && $result['active']=="1") { echo "checked "; }; if ($_SESSION['mailcow_cc_role']=="domainadmin") { echo "disabled"; }; ?>> <?=$lang['edit']['active'];?></label>
+								<label><input type="checkbox" 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>
@@ -277,26 +196,137 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					</div>
 				</form>
 				<?php
-				if (file_exists($GLOBALS["MC_DKIM_TXTS"]. "/" . $domain . "." . "dkim")) {
-					$pubKey = file_get_contents($GLOBALS["MC_DKIM_TXTS"]. "/" . $domain . "." . "dkim");
+				if ($pubkey = dkim_table('get', $result['domain_name'])) {
+				?>
+        <hr>
+        <div class="row">
+          <div class="col-xs-2">
+            <p>Domain: <strong><?=htmlspecialchars($result['domain_name']);?></strong> (dkim._domainkey)</p>
+          </div>
+          <div class="col-xs-10">
+            <pre><?=$pubkey;?></pre>
+          </div>
+        </div>
+				<?php
+				}
+        ?>
+		<hr>
+		<div class="row">
+			<div class="col-sm-6">
+				<h4><span class="glyphicon glyphicon-thumbs-up" aria-hidden="true"></span> <?=$lang['user']['spamfilter_wl'];?></h4>
+				<p><?=$lang['user']['spamfilter_wl_desc'];?></p>
+				<div class="row">
+					<div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_rule'];?></b></div>
+					<div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_action'];?></b></div>
+				</div>
+				<?php
+        $get_policy_list = get_policy_list($domain);
+				if (empty($get_policy_list['whitelist'])):
 				?>
 					<div class="row">
-						<div class="col-xs-2">
-							<p>Domain: <strong><?=htmlspecialchars($domain);?></strong> (dkim._domainkey)</p>
-						</div>
-						<div class="col-xs-9">
-							<pre>v=DKIM1;k=rsa;t=s;s=email;p=<?=$pubKey;?></pre>
-						</div>
-						<div class="col-xs-1">
-							<form class="form-inline" role="form" method="post">
-							<a href="#" onclick="$(this).closest('form').submit()"><span class="glyphicon glyphicon-remove-circle"></span></a>
-							<input type="hidden" name="delete_dkim_record" value="<?=htmlspecialchars($file);?>">
-							<input type="hidden" name="dkim[domain]" value="<?=$domain;?>">
-							</form>
-						</div>
+						<div class="col-sm-12"><i><?=$lang['user']['spamfilter_table_empty'];?></i></div>
 					</div>
 				<?php
-				}
+				else:
+          foreach($get_policy_list['whitelist'] as $wl):
+          ?>
+          <div class="row striped">
+            <form class="form-inline" method="post">
+            <div class="col-xs-6"><code><?=$wl['value'];?></code></div>
+            <div class="col-xs-6">
+              <?php
+              if ($wl['object'] == $domain):
+              ?>
+                <input type="hidden" name="delete_prefid" value="<?=$wl['prefid'];?>">
+                <input type="hidden" name="trigger_set_policy_list">
+                <input type="hidden" name="domain" value="<?=$domain;?>">
+                <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a>
+              <?php
+              else:
+              ?>
+                <span style="cursor:not-allowed"><?=$lang['user']['spamfilter_table_domain_policy'];?></span>
+              <?php
+              endif;
+              ?>
+            </div>
+            </form>
+          </div>
+          <?php
+          endforeach;
+        endif;
+				?>
+				<hr style="margin:5px 0px 7px 0px">
+				<div class="row">
+					<form class="form-inline" method="post">
+					<div class="col-xs-6">
+						<input type="text" class="form-control input-sm" name="object_from" id="object_from" placeholder="*@example.org" required>
+						<input type="hidden" name="object_list" value="wl">
+						<input type="hidden" name="domain" value="<?=$domain;?>">
+					</div>
+					<div class="col-xs-6">
+						<button type="submit" id="trigger_set_policy_list" name="trigger_set_policy_list" class="btn btn-xs btn-default"><?=$lang['user']['spamfilter_table_add'];?></button>
+					</div>
+					</form>
+				</div>
+			</div>
+			<div class="col-sm-6">
+				<h4><span class="glyphicon glyphicon-thumbs-down" aria-hidden="true"></span> <?=$lang['user']['spamfilter_bl'];?></h4>
+				<p><?=$lang['user']['spamfilter_bl_desc'];?></p>
+				<div class="row">
+					<div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_rule'];?></b></div>
+					<div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_action'];?></b></div>
+				</div>
+				<?php
+				if (empty($get_policy_list['blacklist'])):
+				?>
+					<div class="row">
+						<div class="col-sm-12"><i><?=$lang['user']['spamfilter_table_empty'];?></i></div>
+					</div>
+				<?php
+				else:
+          foreach($get_policy_list['blacklist'] as $bl):
+          ?>
+          <div class="row striped">
+            <form class="form-inline" method="post">
+            <div class="col-xs-6"><code><?=$bl['value'];?></code></div>
+            <div class="col-xs-6">
+              <input type="hidden" name="delete_prefid" value="<?=$bl['prefid'];?>">
+              <?php
+              if ($bl['object'] == $domain):
+              ?>
+                <input type="hidden" name="trigger_set_policy_list">
+                <input type="hidden" name="domain" value="<?=$domain;?>">
+                <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a>
+              <?php
+              else:
+              ?>
+                <span style="cursor:not-allowed"><?=$lang['user']['spamfilter_table_domain_policy'];?></span>
+              <?php
+              endif;
+              ?>
+            </div>
+            </form>
+          </div>
+          <?php
+          endforeach;
+        endif;
+				?>
+				<hr style="margin:5px 0px 7px 0px">
+				<div class="row">
+					<form class="form-inline" method="post">
+					<div class="col-xs-6">
+						<input type="text" class="form-control input-sm" name="object_from" id="object_from" placeholder="*@example.org" required>
+						<input type="hidden" name="object_list" value="bl">
+						<input type="hidden" name="domain" value="<?=$domain;?>">
+					</div>
+					<div class="col-xs-6">
+						<button type="submit" id="trigger_set_policy_list" name="trigger_set_policy_list" class="btn btn-xs btn-default"><?=$lang['user']['spamfilter_table_add'];?></button>
+					</div>
+					</form>
+				</div>
+			</div>
+		</div>
+        <?php
 			}
 			else {
 			?>
@@ -308,31 +338,8 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 		is_valid_domain_name($_GET["aliasdomain"]) &&
 		!empty($_GET["aliasdomain"])) {
 			$alias_domain = $_GET["aliasdomain"];
-			try {
-				$stmt = $pdo->prepare("SELECT * FROM `alias_domain`
-					WHERE `alias_domain`= :alias_domain 
-					AND (
-						`target_domain` IN (
-							SELECT `domain` FROM `domain_admins`
-								WHERE `active`='1'
-								AND `username`= :username
-						)
-						OR 'admin'= :admin
-					)");
-				$stmt->execute(array(
-					':alias_domain' => $alias_domain,
-					':username' => $_SESSION['mailcow_cc_username'],
-					':admin' => $_SESSION['mailcow_cc_role']
-				));
-				$result = $stmt->fetch(PDO::FETCH_ASSOC);
-			}
-			catch(PDOException $e) {
-				$_SESSION['return'] = array(
-					'type' => 'danger',
-					'msg' => 'MySQL: '.$e
-				);
-			}
-			if ($result !== false) {
+      $result = mailbox_get_alias_domain_details($alias_domain);
+      if (!empty($result)) {
 			?>
 				<h4><?=$lang['edit']['edit_alias_domain'];?></h4>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
@@ -346,7 +353,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-								<label><input type="checkbox" name="active" <?= (isset($result['active']) && $result['active']=="1") ?  "checked" : null ?>> <?=$lang['edit']['active'];?></label>
+								<label><input type="checkbox" name="active" <?=(isset($result['active_int']) && $result['active_int']=="1") ?  "checked" : null ?>> <?=$lang['edit']['active'];?></label>
 							</div>
 						</div>
 					</div>
@@ -357,35 +364,17 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					</div>
 				</form>
 				<?php
-				$dnstxt_folder = scandir($GLOBALS["MC_DKIM_TXTS"]);
-				$dnstxt_files = array_diff($dnstxt_folder, array('.', '..'));
-				foreach($dnstxt_files as $file) {
-					if (explode("_", $file)[1] == $domain) {
-						$str = file_get_contents($GLOBALS["MC_DKIM_TXTS"]."/".$file);
-						$str = preg_replace('/\r|\t|\n/', '', $str);
-						preg_match('/\(.*\)/im', $str, $matches);
-						if(isset($matches[0])) {
-							$str = str_replace(array(' ', '"', '(', ')'), '', $matches[0]);
-						}
+				if ($pubkey = dkim_table('get', $result['alias_domain'])) {
 				?>
-						<div class="row">
-							<div class="col-xs-2">
-								<p class="text-right"><?=$lang['edit']['dkim_signature'];?></p>
-							</div>
-							<div class="col-xs-10">
-								<div class="col-md-2"><b><?=$lang['edit']['dkim_txt_name'];?></b></div>
-								<div class="col-md-10">
-									<pre><?=htmlspecialchars(explode("_", $file)[0]);?>._domainkey</pre>
-								</div>
-								<div class="col-md-2"><b><?=$lang['edit']['dkim_txt_value'];?></b></div>
-								<div class="col-md-10">
-									<pre><?=htmlspecialchars($str);?></pre>
-									<?=$lang['edit']['dkim_record_info'];?>
-								</div>
-							</div>
+					<div class="row">
+						<div class="col-xs-2">
+							<p>Domain: <strong><?=htmlspecialchars($result['alias_domain']);?></strong> (dkim._domainkey)</p>
 						</div>
+						<div class="col-xs-10">
+							<pre><?=$pubkey;?></pre>
+						</div>
+					</div>
 				<?php
-					}
 				}
 			}
 			else {
@@ -396,22 +385,10 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 	}
 	elseif (isset($_GET['mailbox']) && filter_var($_GET["mailbox"], FILTER_VALIDATE_EMAIL) && !empty($_GET["mailbox"])) {
 			$mailbox = $_GET["mailbox"];
-			try {
-				$stmt = $pdo->prepare("SELECT `username`, `domain`, `name`, `quota`, `active` FROM `mailbox` WHERE `username` = :username1");
-				$stmt->execute(array(
-					':username1' => $mailbox,
-				));
-				$result = $stmt->fetch(PDO::FETCH_ASSOC);
-			}
-			catch(PDOException $e) {
-				$_SESSION['return'] = array(
-					'type' => 'danger',
-					'msg' => 'MySQL: '.$e
-				);
-			}
-			if ($result !== false && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $result['domain'])) {
-				$left_m = remaining_specs($result['domain'], $_GET['mailbox'])['left_m'];
-			?>
+      $result = mailbox_get_mailbox_details($mailbox);
+      if (!empty($result)) {
+        $left_m = remaining_specs($result['domain'], $_GET['mailbox'])['left_m'];
+        ?>
 				<h4><?=$lang['edit']['mailbox'];?></h4>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
 				<input type="hidden" name="username" value="<?=htmlspecialchars($result['username']);?>">
@@ -426,55 +403,59 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 							<br /><span id="quotaBadge" class="badge">max. <?=intval($left_m)?> MiB</span>
 						</label>
 						<div class="col-sm-10">
-							<input type="number" name="quota" id="quota" id="destroyable" style="width:100%" min="1" max="<?=intval($left_m);?>" value="<?=intval($result['quota']) / 1048576;?>" class="form-control">
+							<input type="number" name="quota" id="quota" id="destroyable" style="width:100%" min="1" max="<?=intval($left_m);?>" value="<?=intval($result['quota_bytes']) / 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 style="width:100%" id="sender_acl" name="sender_acl[]" size="10" multiple>
+							<select data-width="50%" style="width:100%" id="sender_acl" name="sender_acl[]" size="10" multiple>
 							<?php
-							$rows = get_sender_acl_handles($mailbox, "preselected");
-							while ($row_goto_from_alias = array_shift($rows)):
-							?>
-								<option disabled selected><?=htmlspecialchars($row_goto_from_alias['address']);?></option>
-							<?php
-							endwhile;
+							$sender_acl_handles = get_sender_acl_handles($mailbox);
 
-							// All manual selected
-							$rows = get_sender_acl_handles($mailbox, "selected");
-							while ($row_selected_sender_acl = array_shift($rows)):
-									if (!filter_var($row_selected_sender_acl['send_as'], FILTER_VALIDATE_EMAIL)):
-									?>
-										<option data-divider="true"></option>
-											<option value="<?=htmlspecialchars($row_selected_sender_acl['send_as']);?>" selected><?=htmlspecialchars(sprintf($lang['edit']['dont_check_sender_acl'], str_replace('@', '', $row_selected_sender_acl['send_as'])));?></option>
-										<option data-divider="true"></option>
-									<?php
-									else:
-									?>
-										<option selected><?=htmlspecialchars($row_selected_sender_acl['send_as']);?></option>
-									<?php
-									endif;
-							endwhile;
-							
-							// Unselected domains
-							$rows = get_sender_acl_handles($mailbox, "unselected-domains");
-							while ($row_unselected_sender_acl = array_shift($rows)):
-							?>
-								<option data-divider="true"></option>
-									<option value="@<?=htmlspecialchars($row_unselected_sender_acl['domain']);?>"><?=htmlspecialchars(sprintf($lang['edit']['dont_check_sender_acl'], $row_unselected_sender_acl['domain']));?></option>
-								<option data-divider="true"></option>
-							<?php
-							endwhile;
+              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;
 
-							// Unselected addresses
-							$rows = get_sender_acl_handles($mailbox, "unselected-addresses");
-							while ($row_unselected_sender_acl = array_shift($rows)):
-							?>
-								<option><?=htmlspecialchars($row_unselected_sender_acl['address']);?></option>
-							<?php
-							endwhile;
-							?>
+              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['fixed_sender_aliases'] as $alias):
+                ?>
+								<option data-subtext="Alias" 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['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']['rw'] as $address):
+                ?>
+                  <option selected><?=htmlspecialchars($address);?></option>
+                <?php
+              endforeach;
+
+              foreach ($sender_acl_handles['sender_acl_addresses']['selectable'] as $address):
+                ?>
+                  <option><?=htmlspecialchars($address);?></option>
+                <?php
+              endforeach;
+
+              ?>
 							</select>
 						</div>
 					</div>
@@ -493,7 +474,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="active" <?=($result['active']=="1") ? "checked" : "";?>> <?=$lang['edit']['active'];?></label>
+							<label><input type="checkbox" name="active" <?=($result['active_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['active'];?></label>
 							</div>
 						</div>
 					</div>
@@ -519,25 +500,10 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 }
 elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "user")) {
 	if (isset($_GET['syncjob']) &&
-    is_numeric($_GET["syncjob"]) &&
-    filter_var($_SESSION['mailcow_cc_username'], FILTER_VALIDATE_EMAIL)) {
+    is_numeric($_GET['syncjob'])) {
 			$id = $_GET["syncjob"];
-      $username = $_SESSION['mailcow_cc_username'];
-			try {
-				$stmt = $pdo->prepare("SELECT * FROM `imapsync` WHERE `user2` = :username AND id = :id");
-				$stmt->execute(array(
-					':username' => $username,
-					':id' => $id
-				));
-				$result = $stmt->fetch(PDO::FETCH_ASSOC);
-			}
-			catch(PDOException $e) {
-				$_SESSION['return'] = array(
-					'type' => 'danger',
-					'msg' => 'MySQL: '.$e
-				);
-      }
-      if ($result && !empty($result)) {
+      $result = get_syncjob_details($id);
+      if (!empty($result)) {
 			?>
 				<h4><?=$lang['edit']['syncjob'];?></h4>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">

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

@@ -21,6 +21,7 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admi
 <?php
 endif;
 ?>
+<div style="margin-bottom:100px"></div>
 <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
 <script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.2/js/bootstrap-switch.min.js"></script>
 <script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/7.0.2/bootstrap-slider.min.js"></script>
@@ -33,6 +34,9 @@ function setLang(sel) {
 }
 
 $(document).ready(function() {
+  $(function () {
+    $('[data-toggle="tooltip"]').tooltip()
+  })
 	// Hide alerts after n seconds
 	$("#alert-fade").fadeTo(7000, 500).slideUp(500, function(){
 		$("#alert-fade").alert('close');

File diff suppressed because it is too large
+ 691 - 384
data/web/inc/functions.inc.php


+ 2 - 2
data/web/inc/init.sql

@@ -115,11 +115,11 @@ CREATE TABLE IF NOT EXISTS `imapsync` (
   `password1` VARCHAR(255) NOT NULL,
   `exclude` VARCHAR(500) NOT NULL DEFAULT '',
   `maxage` SMALLINT NOT NULL DEFAULT '0',
-  `mins_INTerval` VARCHAR(50) NOT NULL,
+  `mins_interval` VARCHAR(50) NOT NULL,
   `port1` SMALLINT NOT NULL,
   `enc1` ENUM('TLS','SSL','PLAIN') DEFAULT 'TLS',
   `delete2duplicates` TINYINT(1) NOT NULL DEFAULT '1',
-  `returned_TEXT` TEXT,
+  `returned_text` TEXT,
   `last_run` TIMESTAMP NULL DEFAULT NULL,
   `created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
   `modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

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

@@ -95,6 +95,9 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 			break;
 		}
 	}
+	if (isset($_POST["trigger_set_policy_list"])) {
+		set_policy_list($_POST);
+	}
 	if (isset($_POST["trigger_mailbox_action"])) {
 		switch ($_POST["trigger_mailbox_action"]) {
 			case "adddomain":

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

@@ -1,5 +1,6 @@
 <?php
 error_reporting(E_ALL);
+//error_reporting(E_ERROR | E_WARNING);
 
 /*
 PLEASE USE THE FILE "vars.local.inc.php" TO OVERWRITE SETTINGS AND MAKE THEM PERSISTENT!

+ 0 - 4
data/web/js/user.js

@@ -14,10 +14,6 @@ $(document).ready(function() {
 			$(".passFields").slideUp();
 		}
 	});
-
-  $(function () {
-    $('[data-toggle="tooltip"]').tooltip()
-  })
 	// Show generate button after time selection
 	$('#trigger_set_time_limited_aliases').hide(); 
 	$('#validity').change(function(){

+ 14 - 8
data/web/lang/lang.de.php

@@ -10,13 +10,13 @@ $lang['footer']['restart_sogo'] = 'SOGo neustarten';
 $lang['footer']['restart_now'] = 'Jetzt neustarten';
 $lang['footer']['restart_sogo_info'] = 'Einige Änderungen an Domains benötigen einen Neustart SOGos. Hier können Sie SOGo neustarten.<br /><br /><b>Wichtig:</b> Ein korrekter Neustart SOGos kann eine Weile in Anspruch nehmen, bitte warten Sie, bis der Prozess vollständig beendet wurde.';
 $lang['dkim']['confirm'] = 'Sind Sie sicher?';
-$lang['danger']['dkim_not_found'] = 'DKIM-Record nicht gefunden';
-$lang['danger']['dkim_remove_failed'] = 'Kann DKIM-Record nicht entfernen';
-$lang['danger']['dkim_add_failed'] = 'Kann DKIM-Record nicht hinzufügen';
+$lang['danger']['dkim_not_found'] = 'DKIM-Key nicht gefunden';
+$lang['danger']['dkim_remove_failed'] = 'Kann DKIM-Key nicht entfernen';
+$lang['danger']['dkim_add_failed'] = 'Kann DKIM-Key nicht hinzufügen';
 $lang['danger']['dkim_domain_or_sel_invalid'] = 'DKIM-Domain oder -Selector nicht korrekt';
 $lang['danger']['dkim_key_length_invalid'] = 'DKIM Schlüssellänge ungültig';
-$lang['success']['dkim_removed'] = 'DKIM-Record wurde entfernt';
-$lang['success']['dkim_added'] = 'DKIM-Record wurde hinzugefügt';
+$lang['success']['dkim_removed'] = 'DKIM-Key wurde entfernt';
+$lang['success']['dkim_added'] = 'DKIM-Key wurde hinzugefügt';
 $lang['danger']['access_denied'] = 'Zugriff verweigert oder unvollständige/ungültige Daten';
 $lang['danger']['whitelist_from_invalid'] = 'Whitelist-Eintrag ist ungültig';
 $lang['danger']['domain_invalid'] = 'Domainname ist ungültig';
@@ -39,6 +39,7 @@ $lang['success']['alias_added'] = 'Alias-Adresse(n) wurden angelegt';
 $lang['success']['alias_modified'] = 'Änderungen an Alias %s wurden gespeichert';
 $lang['success']['aliasd_modified'] = 'Änderungen an Alias-Domain %s wurden gespeichert';
 $lang['success']['mailbox_modified'] = 'Änderungen an Mailbox %s wurden gespeichert';
+$lang['success']['object_modified'] = "Änderungen an Objekt %s wurden gespeichert";
 $lang['success']['msg_size_saved'] = 'Limit wurde gesetzt';
 $lang['danger']['aliasd_not_found'] = 'Alias-Domain nicht gefunden';
 $lang['danger']['targetd_not_found'] = 'Ziel-Domain nicht gefunden';
@@ -137,6 +138,7 @@ $lang['user']['spamfilter_yellow'] = 'Gelb: Die Nachricht ist vielleicht Spam, w
 $lang['user']['spamfilter_red'] = 'Rot: Die Nachricht ist eindeutig Spam und wird vom Server abgelehnt';
 $lang['user']['spamfilter_default_score'] = 'Standardwert:';
 $lang['user']['spamfilter_hint'] = 'Der erste Wert beschreibt den "low spam score", der zweite Wert den "high spam score".';
+$lang['user']['spamfilter_table_domain_policy'] = "n.v. (Domainrichtlinie)";
 
 $lang['user']['tls_policy_warning'] = '<strong>Vorsicht:</strong> Entscheiden Sie sich unverschlüsselte Verbindungen abzulehnen, kann dies dazu führen, dass Kontakte Sie nicht mehr erreichen.<br />Nachrichten, die die Richtlinie nicht erfüllen, werden durch einen Hard-Fail im Mailsystem abgewiesen.';
 $lang['user']['tls_policy'] = 'Verschlüsselungsrichtlinie';
@@ -224,6 +226,7 @@ $lang['mailbox']['remove'] = 'Entfernen';
 $lang['mailbox']['edit'] = 'Bearbeiten';
 $lang['mailbox']['archive'] = 'Archiv-Zugriff';
 $lang['mailbox']['no_record'] = 'Kein Eintrag für Objekt %s';
+$lang['mailbox']['no_record_single'] = 'Kein Eintrag';
 $lang['mailbox']['add_domain'] = 'Domain hinzufügen';
 $lang['mailbox']['add_domain_alias'] = 'Domain-Alias hinzufügen';
 $lang['mailbox']['add_mailbox'] = 'Mailbox hinzufügen';
@@ -378,9 +381,12 @@ $lang['admin']['msg_size_limit_details'] = 'Diese Einstellung wird Postfix und d
 $lang['admin']['save'] = 'Änderungen speichern';
 $lang['admin']['maintenance'] = 'Wartung und Information';
 $lang['admin']['sys_info'] = 'Systeminformation';
-$lang['admin']['dkim_add_key'] = 'DKIM-Record hinzufügen';
-$lang['admin']['dkim_keys'] = 'DKIM-Records';
-$lang['admin']['dkim_key_length'] = 'DKIM Schlüssellänge (Bits)';
+$lang['admin']['dkim_add_key'] = 'DKIM-Key hinzufügen';
+$lang['admin']['dkim_keys'] = 'DKIM-Keys';
+$lang['admin']['dkim_key_valid'] = 'Key gültig';
+$lang['admin']['dkim_key_unused'] = 'Key ohne Zuweisung';
+$lang['admin']['dkim_key_missing'] = 'Key fehlt';
+$lang['admin']['dkim_key_hint'] = 'Der Selector für DKIM-Keys lautet immer <code>dkim</code>.';
 $lang['admin']['add'] = 'Hinzufügen';
 $lang['admin']['configuration'] = 'Konfiguration';
 $lang['admin']['password'] = 'Passwort';

+ 14 - 7
data/web/lang/lang.en.php

@@ -10,13 +10,13 @@ $lang['footer']['restart_sogo'] = 'Restart SOGo';
 $lang['footer']['restart_now'] = 'Restart now';
 $lang['footer']['restart_sogo_info'] = 'Some tasks, e.g. adding a domain, require you to restart SOGo to catch changes made in the mailcow UI.<br /><br /><b>Important:</b> A graceful restart may take a while to complete, please wait for it to finish.';
 $lang['dkim']['confirm'] = "Are you sure?";
-$lang['danger']['dkim_not_found'] = "DKIM record not found";
-$lang['danger']['dkim_remove_failed'] = "Cannot remove selected DKIM record";
-$lang['danger']['dkim_add_failed'] = "Cannot add given DKIM record";
+$lang['danger']['dkim_not_found'] = "DKIM key not found";
+$lang['danger']['dkim_remove_failed'] = "Cannot remove selected DKIM key";
+$lang['danger']['dkim_add_failed'] = "Cannot add given DKIM key";
 $lang['danger']['dkim_domain_or_sel_invalid'] = "DKIM domain or selector invalid";
 $lang['danger']['dkim_key_length_invalid'] = "DKIM key length invalid";
-$lang['success']['dkim_removed'] = "DKIM record has been removed";
-$lang['success']['dkim_added'] = "DKIM record has been saved";
+$lang['success']['dkim_removed'] = "DKIM key has been removed";
+$lang['success']['dkim_added'] = "DKIM key has been saved";
 $lang['danger']['access_denied'] = "Access denied or invalid form data";
 $lang['danger']['whitelist_from_invalid'] = "Whitelist entry invalid";
 $lang['danger']['domain_invalid'] = "Domain name is invalid";
@@ -41,6 +41,7 @@ $lang['success']['alias_added'] = "Alias address/es has/have been added";
 $lang['success']['alias_modified'] = "Changes to alias have been saved";
 $lang['success']['aliasd_modified'] = "Changes to alias domain have been saved";
 $lang['success']['mailbox_modified'] = "Changes to mailbox %s have been saved";
+$lang['success']['object_modified'] = "Changes to object %s have been saved";
 $lang['success']['msg_size_saved'] = "Message size limit has been set";
 $lang['danger']['aliasd_not_found'] = "Alias domain not found";
 $lang['danger']['targetd_not_found'] = "Target domain not found";
@@ -139,6 +140,7 @@ $lang['user']['spamfilter_yellow'] = 'Yellow: this message may be spam, will be
 $lang['user']['spamfilter_red'] = 'Red: This message is spam and will be rejected by the server';
 $lang['user']['spamfilter_default_score'] = 'Default values:';
 $lang['user']['spamfilter_hint'] = 'The first value describes the "low spam score", the second represents the "high spam score".';
+$lang['user']['spamfilter_table_domain_policy'] = "n/a (domain policy)";
 
 $lang['user']['tls_policy_warning'] = '<strong>Warning:</strong> If you decide to enforce encrypted mail transfer, you may lose emails.<br />Messages to not satisfy the policy will be bounced with a hard fail by the mail system.';
 $lang['user']['tls_policy'] = 'Encryption policy';
@@ -226,6 +228,7 @@ $lang['mailbox']['remove'] = 'Remove';
 $lang['mailbox']['edit'] = 'Edit';
 $lang['mailbox']['archive'] = 'Archive';
 $lang['mailbox']['no_record'] = 'No Record for object %s';
+$lang['mailbox']['no_record_single'] = 'No Record';
 $lang['mailbox']['add_domain'] = 'Add domain';
 $lang['mailbox']['add_domain_alias'] = 'Add domain alias';
 $lang['mailbox']['add_mailbox'] = 'Add mailbox';
@@ -379,6 +382,10 @@ $lang['admin']['privacy_anon_mail'] = 'Anonymize outgoing mail';
 $lang['admin']['dkim_txt_name'] = 'TXT record name:';
 $lang['admin']['dkim_txt_value'] = 'TXT record value:';
 $lang['admin']['dkim_key_length'] = 'DKIM key length (bits)';
+$lang['admin']['dkim_key_valid'] = 'Key valid';
+$lang['admin']['dkim_key_unused'] = 'Key unused';
+$lang['admin']['dkim_key_missing'] = 'Key missing';
+$lang['admin']['dkim_key_hint'] = 'Selector for DKIM keys is always dkim.';
 $lang['admin']['previous'] = 'Previous page';
 $lang['admin']['quota_mb'] = 'Quota (MiB):';
 $lang['admin']['sender_acl'] = 'Allow to send as:';
@@ -388,8 +395,8 @@ $lang['admin']['msg_size_limit_details'] = 'Applying a new limit will reload Pos
 $lang['admin']['save'] = 'Save changes';
 $lang['admin']['maintenance'] = 'Maintenance and Information';
 $lang['admin']['sys_info'] = 'System information';
-$lang['admin']['dkim_add_key'] = 'Add DKIM record';
-$lang['admin']['dkim_keys'] = 'DKIM records';
+$lang['admin']['dkim_add_key'] = 'Add DKIM key';
+$lang['admin']['dkim_keys'] = 'DKIM keys';
 $lang['admin']['add'] = 'Add';
 $lang['admin']['configuration'] = 'Configuration';
 $lang['admin']['password'] = 'Password';

+ 2 - 2
data/web/mailbox.php

@@ -1,7 +1,7 @@
 <?php
 require_once "inc/prerequisites.inc.php";
 
-if ($_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")) {
 require_once "inc/header.inc.php";
 $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
 ?>
@@ -91,7 +91,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
             endforeach;
             else:
 							?>
-              <tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['no_record'];?></td></tr>
+              <tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['no_record_single'];?></td></tr>
             <?php
             endif;
             ?>

+ 79 - 127
data/web/user.php

@@ -1,6 +1,5 @@
 <?php
 require_once("inc/prerequisites.inc.php");
-
 if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') {
 	require_once("inc/header.inc.php");
 	$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
@@ -124,40 +123,25 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user
         <p><b><?=$lang['user']['action'];?></b></p>
 			</div>
 			<?php
-			try {
-				$stmt = $pdo->prepare("SELECT `address`,
-					`goto`,
-					`validity`
-						FROM `spamalias`
-							WHERE `goto` = :username
-								AND `validity` >= :unixnow");
-				$stmt->execute(array(':username' => $username, ':unixnow' => time()));
-				$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
-			}
-			catch(PDOException $e) {
-				$_SESSION['return'] = array(
-					'type' => 'danger',
-					'msg' => 'MySQL: '.$e
-				);
-			}
-			if(!empty($rows)):
-			while ($row = array_shift($rows)):
-			?>
-			<div class="col-xs-5">
-				<p><?=htmlspecialchars($row['address']);?></p>
-			</div>
-			<div class="col-xs-4">
-				<p><?=htmlspecialchars(date($lang['user']['alias_full_date'], $row['validity']));?></p>
-			</div>
-			<div class="col-xs-3">
-				<form class="form-inline" role="form" method="post">
-          <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a>
-          <input type="hidden" name="trigger_set_time_limited_aliases" value="delete">
-          <input type="hidden" name="item" value="<?=htmlspecialchars($row['address']);?>">
-				</form>
-			</div>
-			<?php
-			endwhile;
+      $get_time_limited_aliases = get_time_limited_aliases($username);
+      if (!empty($get_time_limited_aliases)):
+        foreach ($get_time_limited_aliases as $row):
+        ?>
+        <div class="col-xs-5">
+          <p><?=htmlspecialchars($row['address']);?></p>
+        </div>
+        <div class="col-xs-4">
+          <p><?=htmlspecialchars(date($lang['user']['alias_full_date'], $row['validity']));?></p>
+        </div>
+        <div class="col-xs-3">
+          <form class="form-inline" role="form" method="post">
+            <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a>
+            <input type="hidden" name="trigger_set_time_limited_aliases" value="delete">
+            <input type="hidden" name="item" value="<?=htmlspecialchars($row['address']);?>">
+          </form>
+        </div>
+        <?php
+        endforeach;
 			else:
 			?>
       <div class="col-xs-12">
@@ -233,49 +217,39 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user
 					<div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_action'];?></b></div>
 				</div>
 				<?php
-				try {
-					$stmt = $pdo->prepare("SELECT `value`, `prefid` FROM `filterconf` WHERE `option`='whitelist_from' AND `object`= :username");
-					$stmt->execute(array(':username' => $username));
-					$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
-				}
-				catch(PDOException $e) {
-					$_SESSION['return'] = array(
-						'type' => 'danger',
-						'msg' => 'MySQL: '.$e
-					);
-				}
-				if (count($rows) == 0):
+        $get_policy_list = get_policy_list($username);
+				if (empty($get_policy_list['whitelist'])):
 				?>
 					<div class="row">
 						<div class="col-sm-12"><i><?=$lang['user']['spamfilter_table_empty'];?></i></div>
 					</div>
 				<?php
-				endif;
-				while ($whitelistRow = array_shift($rows)):
-				?>
-				<div class="row striped">
-					<form class="form-inline" method="post">
-					<div class="col-xs-6"><code><?=$whitelistRow['value'];?></code></div>
-					<div class="col-xs-6">
-						<input type="hidden" name="prefid" value="<?=$whitelistRow['prefid'];?>">
-						<?php
-						if ($whitelistRow['username'] != array_pop(explode('@', $username))):
-						?>
-							<input type="hidden" name="trigger_set_policy_list">
-							<a href="#n" onclick="$(this).closest('form').submit()"><?=$lang['user']['spamfilter_table_remove'];?></a>
-						<?php
-						else:
-						?>
-							<span style="cursor:not-allowed"><?=$lang['user']['spamfilter_table_domain_policy'];?></span>
-						<?php
-						endif;
-						?>
-					</div>
-					</form>
-				</div>
-
-				<?php
-				endwhile;
+				else:
+          foreach($get_policy_list['whitelist'] as $wl):
+          ?>
+          <div class="row striped">
+            <form class="form-inline" method="post">
+            <div class="col-xs-6"><code><?=$wl['value'];?></code></div>
+            <div class="col-xs-6">
+              <input type="hidden" name="delete_prefid" value="<?=$wl['prefid'];?>">
+              <?php
+              if (filter_var($wl['object'], FILTER_VALIDATE_EMAIL)):
+              ?>
+                <input type="hidden" name="trigger_set_policy_list">
+                <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a>
+              <?php
+              else:
+              ?>
+                <span style="cursor:not-allowed"><?=$lang['user']['spamfilter_table_domain_policy'];?></span>
+              <?php
+              endif;
+              ?>
+            </div>
+            </form>
+          </div>
+          <?php
+          endforeach;
+        endif;
 				?>
 				<hr style="margin:5px 0px 7px 0px">
 				<div class="row">
@@ -298,48 +272,38 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user
 					<div class="col-sm-6"><b><?=$lang['user']['spamfilter_table_action'];?></b></div>
 				</div>
 				<?php
-				try {
-					$stmt = $pdo->prepare("SELECT `value`, `prefid` FROM `filterconf` WHERE `option`='blacklist_from' AND `object`= :username");
-					$stmt->execute(array(':username' => $username));
-					$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
-				}
-				catch(PDOException $e) {
-					$_SESSION['return'] = array(
-						'type' => 'danger',
-						'msg' => 'MySQL: '.$e
-					);
-				}
-				if (count($rows) == 0):
+				if (empty($get_policy_list['blacklist'])):
 				?>
 					<div class="row">
 						<div class="col-sm-12"><i><?=$lang['user']['spamfilter_table_empty'];?></i></div>
 					</div>
 				<?php
-				endif;
-				while ($blacklistRow = array_shift($rows)):
-				?>
-				<div class="row striped">
-					<form class="form-inline" method="post">
-					<div class="col-xs-6"><code><?=$blacklistRow['value'];?></code></div>
-					<div class="col-xs-6">
-						<input type="hidden" name="prefid" value="<?=$blacklistRow['prefid'];?>">
-						<?php
-						if ($blacklistRow['username'] != array_pop(explode('@', $username))):
-						?>
-							<input type="hidden" name="trigger_set_policy_list">
-							<a href="#n" onclick="$(this).closest('form').submit()"><?=$lang['user']['spamfilter_table_remove'];?></a>
-						<?php
-						else:
-						?>
-							<span style="cursor:not-allowed"><?=$lang['user']['spamfilter_table_domain_policy'];?></span>
-						<?php
-						endif;
-						?>
-					</div>
-					</form>
-				</div>
-				<?php
-				endwhile;
+				else:
+          foreach($get_policy_list['blacklist'] as $bl):
+          ?>
+          <div class="row striped">
+            <form class="form-inline" method="post">
+            <div class="col-xs-6"><code><?=$bl['value'];?></code></div>
+            <div class="col-xs-6">
+              <?php
+              if (filter_var($bl['object'], FILTER_VALIDATE_EMAIL)):
+              ?>
+                <input type="hidden" name="delete_prefid" value="<?=$bl['prefid'];?>">
+                <input type="hidden" name="trigger_set_policy_list">
+                <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a>
+              <?php
+              else:
+              ?>
+                <span style="cursor:not-allowed"><?=$lang['user']['spamfilter_table_domain_policy'];?></span>
+              <?php
+              endif;
+              ?>
+            </div>
+            </form>
+          </div>
+          <?php
+          endforeach;
+        endif;
 				?>
 				<hr style="margin:5px 0px 7px 0px">
 				<div class="row">
@@ -398,21 +362,9 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user
 			</thead>
 			<tbody>
 			<?php
-			try {
-				$stmt = $pdo->prepare("SELECT *, CONCAT(LEFT(`password1`, 3), '…') as `password1_short`
-						FROM `imapsync`
-							WHERE `user2` = :username");
-				$stmt->execute(array(':username' => $username));
-				$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
-			}
-			catch(PDOException $e) {
-				$_SESSION['return'] = array(
-					'type' => 'danger',
-					'msg' => 'MySQL: '.$e
-				);
-			}
-			if(!empty($rows)):
-			while ($row = array_shift($rows)):
+      $get_syncjobs = get_syncjobs($username);
+			if (!empty($get_syncjobs)):
+			foreach ($get_syncjobs as $row):
 			?>
 				<tr id="data">
 				<td><?=htmlspecialchars($row['host1'] . ':' . $row['port1']);?></td>
@@ -442,7 +394,7 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user
         </td>
 				</tr>
 			<?php
-			endwhile;
+			endforeach;
 			else:
 			?>
 				<tr id="no-data"><td colspan="9" style="text-align: center; font-style: italic;"><?=$lang['user']['no_record'];?></td></tr>
@@ -462,7 +414,7 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user
 		</div>
 	</div>
 </div>
-<br />
+<div style="margin-bottom:200px;"></div>
 <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">

Some files were not shown because too many files changed in this diff