Page MenuHomeWMGMC Issues

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/data/web/add.php b/data/web/add.php
index e7b73d13..276082df 100644
--- a/data/web/add.php
+++ b/data/web/add.php
@@ -1,353 +1,365 @@
<?php
require_once("inc/prerequisites.inc.php");
$AuthUsers = array("admin", "domainadmin", "user");
if (!isset($_SESSION['mailcow_cc_role']) OR !in_array($_SESSION['mailcow_cc_role'], $AuthUsers)) {
header('Location: /');
exit();
}
require_once("inc/header.inc.php");
?>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><?=$lang['add']['title'];?></h3>
</div>
<div class="panel-body">
<?php
if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "admin" || $_SESSION['mailcow_cc_role'] == "domainadmin")) {
if (isset($_GET['domain']) && $_SESSION['mailcow_cc_role'] == "admin") {
?>
<h4><?=$lang['add']['domain'];?></h4>
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<div class="form-group">
<label class="control-label col-sm-2" for="domain"><?=$lang['add']['domain'];?>:</label>
<div class="col-sm-10">
<input type="text" autocorrect="off" autocapitalize="none" class="form-control" name="domain" id="domain">
</div>
</div>
<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">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="aliases"><?=$lang['add']['max_aliases'];?></label>
<div class="col-sm-10">
<input type="number" class="form-control" name="aliases" id="aliases" value="400">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="mailboxes"><?=$lang['add']['max_mailboxes'];?></label>
<div class="col-sm-10">
<input type="number" class="form-control" name="mailboxes" id="mailboxes" value="10">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="maxquota"><?=$lang['add']['mailbox_quota_m'];?></label>
<div class="col-sm-10">
<input type="number" class="form-control" name="maxquota" id="maxquota" value="3072">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="quota"><?=$lang['add']['domain_quota_m'];?></label>
<div class="col-sm-10">
<input type="number" class="form-control" name="quota" id="quota" value="10240">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2"><?=$lang['add']['backup_mx_options'];?></label>
<div class="col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="backupmx"> <?=$lang['add']['relay_domain'];?></label>
<br />
<label><input type="checkbox" name="relay_all_recipients"> <?=$lang['add']['relay_all'];?></label>
<p><?=$lang['add']['relay_all_info'];?></p>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="active" checked> <?=$lang['add']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_mailbox_action" value="adddomain" class="btn btn-success"><?=$lang['add']['save'];?></button>
</div>
</div>
<p><span class="glyphicon glyphicon-exclamation-sign text-danger"></span> <?=$lang['add']['restart_sogo_hint'];?></p>
</form>
<?php
}
elseif (isset($_GET['alias'])) {
?>
<h4><?=$lang['add']['alias'];?></h4>
<p><?=$lang['add']['alias_spf_fail'];?></p>
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<div class="form-group">
<label class="control-label col-sm-2" for="address"><?=$lang['add']['alias_address'];?></label>
<div class="col-sm-10">
<textarea autocorrect="off" autocapitalize="none" class="form-control" rows="5" name="address" id="address"></textarea>
<p><?=$lang['add']['alias_address_info'];?></p>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="goto"><?=$lang['add']['target_address'];?></label>
<div class="col-sm-10">
<textarea autocorrect="off" autocapitalize="none" class="form-control" rows="5" id="goto" name="goto"></textarea>
<p><?=$lang['add']['target_address_info'];?></p>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="active" checked> <?=$lang['add']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_mailbox_action" value="addalias" class="btn btn-success "><?=$lang['add']['save'];?></button>
</div>
</div>
</form>
<?php
}
elseif (isset($_GET['aliasdomain'])) {
?>
<h4><?=$lang['add']['alias_domain'];?></h4>
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<div class="form-group">
<label class="control-label col-sm-2" for="alias_domain"><?=$lang['add']['alias_domain'];?></label>
<div class="col-sm-10">
<textarea autocorrect="off" autocapitalize="none" class="form-control" rows="5" name="alias_domain" id="alias_domain"></textarea>
<p><?=$lang['add']['alias_domain_info'];?></p>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="target_domain"><?=$lang['add']['target_domain'];?></label>
<div class="col-sm-10">
<select name="target_domain" id="target_domain" title="<?=$lang['add']['select'];?>">
<?php
try {
$stmt = $pdo->prepare("SELECT `domain` FROM `domain`
WHERE `domain` IN (
SELECT `domain` FROM `domain_admins`
WHERE `username`= :username
AND `active`='1'
)
OR 'admin' = :admin");
$stmt->execute(array(':username' => $_SESSION['mailcow_cc_username'], ':admin' => $_SESSION['mailcow_cc_role']));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
while ($row = array_shift($rows)) {
echo "<option>".htmlspecialchars($row['domain'])."</option>";
}
?>
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="active" checked> <?=$lang['add']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_mailbox_action" value="addaliasdomain" class="btn btn-success "><?=$lang['add']['save'];?></button>
</div>
</div>
</form>
<?php
}
elseif (isset($_GET['mailbox'])) {
?>
<h4><?=$lang['add']['mailbox'];?></h4>
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<div class="form-group">
<label class="control-label col-sm-2" for="local_part"><?=$lang['add']['mailbox_username'];?></label>
<div class="col-sm-10">
<input type="text" pattern="[A-Za-z0-9\.!#$%&'*+/=?^_`{|}~-]+" autocorrect="off" autocapitalize="none" class="form-control" name="local_part" id="local_part" required>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="domain"><?=$lang['add']['domain'];?>:</label>
<div class="col-sm-10">
<select id="addSelectDomain" name="domain" id="domain" title="<?=$lang['add']['select'];?>" required>
<?php
try {
$stmt = $pdo->prepare("SELECT `domain` FROM `domain`
WHERE `domain` IN (
SELECT `domain` FROM `domain_admins`
WHERE `username`= :username
AND `active`='1'
)
OR 'admin' = :admin");
$stmt->execute(array(':username' => $_SESSION['mailcow_cc_username'], ':admin' => $_SESSION['mailcow_cc_role']));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
}
while ($row = array_shift($rows)) {
echo "<option>".htmlspecialchars($row['domain'])."</option>";
}
?>
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="name"><?=$lang['add']['full_name'];?></label>
<div class="col-sm-10">
<input type="text" class="form-control" name="name" id="name">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="addInputQuota"><?=$lang['add']['quota_mb'];?>
<br /><span id="quotaBadge" class="badge">max. - MiB</span>
</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="quota" min="1" max="" id="addInputQuota" disabled value="<?=$lang['add']['select_domain'];?>" required>
</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" placeholder="">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="password2"><?=$lang['add']['password_repeat'];?></label>
<div class="col-sm-10">
<input type="password" class="form-control" name="password2" id="password2" placeholder="">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="active" checked> <?=$lang['add']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_mailbox_action" value="addmailbox" class="btn btn-success "><?=$lang['add']['save'];?></button>
</div>
</div>
</form>
<?php
}
else {
?>
<div class="alert alert-info" role="alert"><?=$lang['info']['no_action'];?></div>
<?php
}
}
-if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "user")) {
+elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "user")) {
if (isset($_GET['syncjob'])) {
?>
<h4><?=$lang['add']['syncjob'];?></h4>
<p><?=$lang['add']['syncjob_hint'];?></p>
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<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">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="text" 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" 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" name="active" checked> <?=$lang['add']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_add_syncjob" value="1" class="btn btn-success "><?=$lang['add']['save'];?></button>
</div>
</div>
</form>
<?php
}
}
else {
?>
<div class="alert alert-danger" role="alert"><?=$lang['danger']['access_denied'];?></div>
<?php
}
?>
</div>
</div>
</div>
</div>
<a href="<?=$_SESSION['return_to'];?>">&#8592; <?=$lang['add']['previous'];?></a>
</div> <!-- /container -->
<script src="js/add.js"></script>
<?php
require_once("inc/footer.inc.php");
?>
diff --git a/data/web/edit.php b/data/web/edit.php
index b89ba1cd..3ab5fff0 100644
--- a/data/web/edit.php
+++ b/data/web/edit.php
@@ -1,632 +1,644 @@
<?php
require_once("inc/prerequisites.inc.php");
$AuthUsers = array("admin", "domainadmin", "user");
if (!isset($_SESSION['mailcow_cc_role']) OR !in_array($_SESSION['mailcow_cc_role'], $AuthUsers)) {
header('Location: /');
exit();
}
require_once("inc/header.inc.php");
?>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><?=$lang['edit']['title'];?></h3>
</div>
<div class="panel-body">
<?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"];
$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) {
?>
<h4><?=$lang['edit']['alias'];?></h4>
<br />
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<input type="hidden" name="address" value="<?=htmlspecialchars($alias);?>">
<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" name="active" <?php if (isset($result['active']) && $result['active']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_mailbox_action" value="editalias" class="btn btn-success btn-sm"><?=$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"];
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) {
?>
<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="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)):
?>
<option selected><?=htmlspecialchars($row_selected['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)):
?>
<option><?=htmlspecialchars($row_unselected['domain']);?></option>
<?php
endwhile;
?>
</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" name="active" <?php if (isset($result['active']) && $result['active']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_edit_domain_admin" class="btn btn-success btn-sm"><?=$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"];
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) {
?>
<h4><?=$lang['edit']['domain'];?></h4>
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<input type="hidden" name="domain" value="<?=htmlspecialchars($domain);?>">
<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['aliases']);?>">
</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']);?>">
</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']);?>">
</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']);?>">
</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>
<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>
<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" name="active" <?php if (isset($result['active']) && $result['active']=="1") { echo "checked "; }; if ($_SESSION['mailcow_cc_role']=="domainadmin") { echo "disabled"; }; ?>> <?=$lang['edit']['active'];?></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_mailbox_action" value="editdomain" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
</div>
</div>
</form>
<?php
if (file_exists($GLOBALS["MC_DKIM_TXTS"]. "/" . $domain . "." . "dkim")) {
$pubKey = file_get_contents($GLOBALS["MC_DKIM_TXTS"]. "/" . $domain . "." . "dkim");
?>
<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
}
}
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"];
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) {
?>
<h4><?=$lang['edit']['edit_alias_domain'];?></h4>
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<input type="hidden" name="alias_domain_now" value="<?=htmlspecialchars($alias_domain);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="alias_domain"><?=$lang['edit']['alias_domain'];?></label>
<div class="col-sm-10">
<input type="text" class="form-control" name="alias_domain" id="alias_domain" value="<?=htmlspecialchars($result['alias_domain']);?>">
</div>
</div>
<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>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" name="trigger_mailbox_action" value="editaliasdomain" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
</div>
</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]);
}
?>
<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>
<?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"];
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'];
?>
<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']);?>">
<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($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">
</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>
<?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;
// 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;
// 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;
?>
</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="<?=$lang['edit']['unchanged_if_empty'];?>">
</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" 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 type="submit" name="trigger_mailbox_action" value="editmailbox" class="btn btn-success btn-sm"><?=$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
}
}
-if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "user")) {
+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)) {
$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)) {
?>
<h4><?=$lang['edit']['syncjob'];?></h4>
<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
<input type="hidden" name="id" value="<?=htmlspecialchars($result['id']);?>">
<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="text" 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" 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 type="submit" name="trigger_edit_syncjob" value="1" class="btn btn-success btn-sm"><?=$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
}
}
else {
?>
<div class="alert alert-danger" role="alert"><?=$lang['danger']['access_denied'];?></div>
<?php
}
?>
</div>
</div>
</div>
</div>
<a href="<?=$_SESSION['return_to'];?>">&#8592; <?=$lang['edit']['previous'];?></a>
</div> <!-- /container -->
<?php
require_once("inc/footer.inc.php");
?>
diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php
index 5ed427b2..c21b6d2a 100644
--- a/data/web/inc/functions.inc.php
+++ b/data/web/inc/functions.inc.php
@@ -1,3023 +1,3474 @@
<?php
function hash_password($password) {
$salt_str = bin2hex(openssl_random_pseudo_bytes(8));
return "{SSHA256}".base64_encode(hash('sha256', $password . $salt_str, true) . $salt_str);
}
function hasDomainAccess($username, $role, $domain) {
global $pdo;
if (!filter_var($username, FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
return false;
}
if (!is_valid_domain_name($domain)) {
return false;
}
if ($role != 'admin' && $role != 'domainadmin' && $role != 'user') {
return false;
}
try {
$stmt = $pdo->prepare("SELECT `domain` FROM `domain_admins`
WHERE (
`active`='1'
AND `username` = :username
AND `domain` = :domain
)
OR 'admin' = :role");
$stmt->execute(array(':username' => $username, ':domain' => $domain, ':role' => $role));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
} catch(PDOException $e) {
error_log($e);
return false;
}
if ($num_results != 0 && !empty($num_results)) {
return true;
}
return false;
}
function init_db_schema() {
global $pdo;
try {
- $stmt = $pdo->prepare("SELECT `username` FROM `admin`");
+ $stmt = $pdo->prepare("SELECT NULL FROM `admin`, `imapsync`");
$stmt->execute();
}
catch (Exception $e) {
$lines = file('/web/inc/init.sql');
$data = '';
foreach ($lines as $line) {
if (substr($line, 0, 2) == '--' || $line == '') {
continue;
}
$data .= $line;
if (substr(trim($line), -1, 1) == ';') {
$pdo->query($data);
$data = '';
}
}
// Create index if not exists
$stmt = $pdo->query("SHOW INDEX FROM sogo_acl WHERE KEY_NAME = 'sogo_acl_c_folder_id_idx'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results == 0) {
$pdo->query("CREATE INDEX sogo_acl_c_folder_id_idx ON sogo_acl(c_folder_id)");
}
$stmt = $pdo->query("SHOW INDEX FROM sogo_acl WHERE KEY_NAME = 'sogo_acl_c_uid_idx'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results == 0) {
$pdo->query("CREATE INDEX sogo_acl_c_uid_idx ON sogo_acl(c_uid)");
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => 'Database initialization completed.'
);
}
// Add newly added columns
$stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE 'kind'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results == 0) {
$pdo->query("ALTER TABLE `mailbox` ADD `kind` varchar(100) NOT NULL DEFAULT ''");
}
$stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE 'multiple_bookings'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results == 0) {
$pdo->query("ALTER TABLE `mailbox` ADD `multiple_bookings` tinyint(1) NOT NULL DEFAULT '0'");
}
$stmt = $pdo->query("SHOW COLUMNS FROM `mailbox` LIKE 'wants_tagged_subject'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results == 0) {
$pdo->query("ALTER TABLE `mailbox` ADD `wants_tagged_subject` tinyint(1) NOT NULL DEFAULT '0'");
}
- $stmt = $pdo->query("SELECT * FROM information_schema.TABLES WHERE TABLE_NAME = 'imapsync'");
- $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
-
- if ($num_results == 0) {
- $pdo->query("CREATE TABLE IF NOT EXISTS `imapsync` (
- `id` int NOT NULL AUTO_INCREMENT,
- `user2` VARCHAR(255) NOT NULL,
- `host1` VARCHAR(255) NOT NULL,
- `authmech1` ENUM('PLAIN','LOGIN','CRAM-MD5') DEFAULT 'PLAIN',
- `user1` VARCHAR(255) NOT NULL,
- `exclude` VARCHAR(500) NOT NULL DEFAULT '',
- `password1` VARCHAR(255) 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,
- `last_run` TIMESTAMP NULL DEFAULT NULL,
- `created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `active` TINYINT(1) NOT NULL DEFAULT '0',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;");
- }
}
function verify_ssha256($hash, $password) {
// Remove tag if any
$hash = ltrim($hash, '{SSHA256}');
// Decode hash
$dhash = base64_decode($hash);
// Get first 32 bytes of binary which equals a SHA256 hash
$ohash = substr($dhash, 0, 32);
// Remove SHA256 hash from decoded hash to get original salt string
$osalt = str_replace($ohash, '', $dhash);
// Check single salted SHA256 hash against extracted hash
if (hash('sha256', $password . $osalt, true) == $ohash) {
return true;
}
else {
return false;
}
}
function doveadm_authenticate($hash, $algorithm, $password) {
$descr = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
$pipes = array();
$process = proc_open("/usr/bin/doveadm pw -s ".$algorithm." -t '".$hash."'", $descr, $pipes);
if (is_resource($process)) {
fputs($pipes[0], $password);
fclose($pipes[0]);
while ($f = fgets($pipes[1])) {
if (preg_match('/(verified)/', $f)) {
proc_close($process);
return true;
}
return false;
}
fclose($pipes[1]);
while ($f = fgets($pipes[2])) {
proc_close($process);
return false;
}
fclose($pipes[2]);
proc_close($process);
}
return false;
}
function check_login($user, $pass) {
global $pdo;
if (!filter_var($user, FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $user))) {
return false;
}
$user = strtolower(trim($user));
$stmt = $pdo->prepare("SELECT `password` FROM `admin`
WHERE `superadmin` = '1'
AND `username` = :user");
$stmt->execute(array(':user' => $user));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
if (verify_ssha256($row['password'], $pass) !== false) {
unset($_SESSION['ldelay']);
return "admin";
}
}
$stmt = $pdo->prepare("SELECT `password` FROM `admin`
WHERE `superadmin` = '0'
AND `active`='1'
AND `username` = :user");
$stmt->execute(array(':user' => $user));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
if (verify_ssha256($row['password'], $pass) !== false) {
unset($_SESSION['ldelay']);
return "domainadmin";
}
}
$stmt = $pdo->prepare("SELECT `password` FROM `mailbox`
WHERE `active`='1'
AND `username` = :user");
$stmt->execute(array(':user' => $user));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
if (verify_ssha256($row['password'], $pass) !== false) {
unset($_SESSION['ldelay']);
return "user";
}
}
if (!isset($_SESSION['ldelay'])) {
$_SESSION['ldelay'] = "0";
}
elseif (!isset($_SESSION['mailcow_cc_username'])) {
$_SESSION['ldelay'] = $_SESSION['ldelay']+0.5;
}
sleep($_SESSION['ldelay']);
}
function formatBytes($size, $precision = 2) {
if(!is_numeric($size)) {
return "0";
}
$base = log($size, 1024);
$suffixes = array(' Byte', ' KiB', ' MiB', ' GiB', ' TiB');
if ($size == "0") {
return "0";
}
return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
}
function dkim_table($action, $item) {
global $lang;
switch ($action) {
case "delete":
$domain = preg_replace('/[^A-Za-z0-9._\-]/', '_', $item['dkim']['domain']);
if (!is_valid_domain_name($domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
);
break;
}
exec('rm ' . escapeshellarg($GLOBALS['MC_DKIM_TXTS'] . '/' . $domain . '.dkim'), $out, $return);
if ($return != "0") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['dkim_remove_failed'])
);
break;
}
exec('rm ' . escapeshellarg($GLOBALS['MC_DKIM_KEYS'] . '/' . $domain . '.dkim'), $out, $return);
if ($return != "0") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['dkim_remove_failed'])
);
break;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['dkim_removed'])
);
break;
case "add":
$domain = preg_replace('/[^A-Za-z0-9._\-]/', '_', $item['dkim']['domain']);
$key_length = intval($item['dkim']['key_size']);
if (!is_valid_domain_name($domain) || !is_numeric($key_length)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
);
break;
}
if (!empty(glob($GLOBALS['MC_DKIM_TXTS'] . '/' . $domain . '.dkim'))) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid'])
);
break;
}
$config = array(
"digest_alg" => "sha256",
"private_key_bits" => $key_length,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$keypair_ressource = openssl_pkey_new($config);
$key_details = openssl_pkey_get_details($keypair_ressource);
$pubKey = implode(array_slice(
array_filter(
explode(PHP_EOL, $key_details['key'])
), 1, -1)
);
// Save public key to file
file_put_contents($GLOBALS['MC_DKIM_TXTS'] . '/' . $domain . '.dkim', $pubKey);
// Save private key to file
openssl_pkey_export_to_file($keypair_ressource, $GLOBALS['MC_DKIM_KEYS'] . '/' . $domain . '.dkim');
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['dkim_added'])
);
break;
}
}
function mailbox_add_domain($postarray) {
+ // Array elements
+ // domain string
+ // description string
+ // aliases int
+ // mailboxes int
+ // maxquota int
+ // quota int
+ // active int
+ // relay_all_recipients int
+ // backupmx int
global $pdo;
global $lang;
if ($_SESSION['mailcow_cc_role'] != "admin") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
$domain = idn_to_ascii(strtolower(trim($postarray['domain'])));
- $description = $postarray['description'];
+ $description = $postarray['description'];
$aliases = $postarray['aliases'];
- $mailboxes = $postarray['mailboxes'];
+ $mailboxes = $postarray['mailboxes'];
$maxquota = $postarray['maxquota'];
$quota = $postarray['quota'];
if ($maxquota > $quota) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['mailbox_quota_exceeds_domain_quota'])
);
return false;
}
- isset($postarray['active']) ? $active = '1' : $active = '0';
- isset($postarray['relay_all_recipients']) ? $relay_all_recipients = '1' : $relay_all_recipients = '0';
- isset($postarray['backupmx']) ? $backupmx = '1' : $backupmx = '0';
- isset($postarray['relay_all_recipients']) ? $backupmx = '1' : true;
+ isset($postarray['active']) ? $active = '1' : $active = '0';
+ isset($postarray['relay_all_recipients']) ? $relay_all_recipients = '1' : $relay_all_recipients = '0';
+ isset($postarray['backupmx']) ? $backupmx = '1' : $backupmx = '0';
+ isset($postarray['relay_all_recipients']) ? $backupmx = '1' : true;
if (!is_valid_domain_name($domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['domain_invalid'])
);
return false;
}
foreach (array($quota, $maxquota, $mailboxes, $aliases) as $data) {
if (!is_numeric($data)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['object_is_not_numeric'], htmlspecialchars($data))
);
return false;
}
}
try {
$stmt = $pdo->prepare("SELECT `domain` FROM `domain`
WHERE `domain` = :domain");
$stmt->execute(array(':domain' => $domain));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
$stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain`
WHERE `alias_domain` = :domain");
$stmt->execute(array(':domain' => $domain));
$num_results = $num_results + count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results != 0) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['domain_exists'], htmlspecialchars($domain))
);
return false;
}
try {
$stmt = $pdo->prepare("INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `maxquota`, `quota`, `transport`, `backupmx`, `created`, `modified`, `active`, `relay_all_recipients`)
VALUES (:domain, :description, :aliases, :mailboxes, :maxquota, :quota, 'virtual', :backupmx, :created, :modified, :active, :relay_all_recipients)");
$stmt->execute(array(
':domain' => $domain,
':description' => $description,
':aliases' => $aliases,
':mailboxes' => $mailboxes,
':maxquota' => $maxquota,
':quota' => $quota,
':backupmx' => $backupmx,
':active' => $active,
':created' => date('Y-m-d H:i:s'),
':modified' => date('Y-m-d H:i:s'),
':relay_all_recipients' => $relay_all_recipients
));
- //
- // PoC for a restart with supervisord unix socket
- // * $sock = stream_socket_client("unix:///var/run/controller/supervisord.sock", $errno, $errstr, 30);
- // * fwrite($sock, "GET ?processname=sogo&action=restart HTTP/1.0\r\nAccept: */*\r\n\r\n");
- // * fclose($sock);
- //
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['domain_added'], htmlspecialchars($domain))
);
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
function mailbox_add_alias($postarray) {
+ // Array elements
+ // address string (separated by " ", "," ";" "\n") - email address or domain
+ // goto string (separated by " ", "," ";" "\n")
+ // active int
global $lang;
global $pdo;
- $addresses = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['address']));
- $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
+ $addresses = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['address']));
+ $gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
isset($postarray['active']) ? $active = '1' : $active = '0';
if (empty($addresses[0])) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['alias_empty'])
);
return false;
}
if (empty($gotos[0])) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['goto_empty'])
);
return false;
}
foreach ($addresses as $address) {
if (empty($address)) {
continue;
}
- $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
- $local_part = strstr($address, '@', true);
- $address = $local_part.'@'.$domain;
+ $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
+ $local_part = strstr($address, '@', true);
+ $address = $local_part.'@'.$domain;
+
+ try {
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
+ WHERE `domain`= :domain");
+ $stmt->execute(array(':domain' => $domain));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if ($num_results == 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_not_found'], $domain)
+ );
+ return false;
+ }
if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['alias_invalid'])
);
return false;
}
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `address` FROM `alias`
WHERE `address`= :address");
$stmt->execute(array(':address' => $address));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results != 0) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['is_alias_or_mailbox'], htmlspecialchars($address))
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `address` FROM `spamalias`
WHERE `address`= :address");
$stmt->execute(array(':address' => $address));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results != 0) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($address))
);
return false;
}
foreach ($gotos as &$goto) {
if (empty($goto)) {
continue;
}
$goto_domain = idn_to_ascii(substr(strstr($goto, '@'), 1));
$goto_local_part = strstr($goto, '@', true);
$goto = $goto_local_part.'@'.$goto_domain;
if (!filter_var($goto, FILTER_VALIDATE_EMAIL) === true) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['goto_invalid'])
);
return false;
}
if ($goto == $address) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['alias_goto_identical'])
);
return false;
}
}
$gotos = array_filter($gotos);
$goto = implode(",", $gotos);
try {
$stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `created`, `modified`, `active`)
VALUES (:address, :goto, :domain, :created, :modified, :active)");
if (!filter_var($address, FILTER_VALIDATE_EMAIL) === true) {
$stmt->execute(array(
':address' => '@'.$domain,
':goto' => $goto,
':domain' => $domain,
':created' => date('Y-m-d H:i:s'),
':modified' => date('Y-m-d H:i:s'),
':active' => $active
));
}
else {
$stmt->execute(array(
':address' => $address,
':goto' => $goto,
':domain' => $domain,
':created' => date('Y-m-d H:i:s'),
':modified' => date('Y-m-d H:i:s'),
':active' => $active
));
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['alias_added'])
);
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['alias_added'])
);
}
function mailbox_add_alias_domain($postarray) {
+ // Array elements
+ // active int
+ // alias_domain string
+ // target_domain string
global $lang;
global $pdo;
isset($postarray['active']) ? $active = '1' : $active = '0';
+ $alias_domain = idn_to_ascii(strtolower(trim($postarray['alias_domain'])));
+ $target_domain = idn_to_ascii(strtolower(trim($postarray['target_domain'])));
- if (!is_valid_domain_name($postarray['alias_domain'])) {
+ if (!is_valid_domain_name($alias_domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['alias_domain_invalid'])
);
return false;
}
- if (!is_valid_domain_name($postarray['target_domain'])) {
+ if (!is_valid_domain_name($target_domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['target_domain_invalid'])
);
return false;
}
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $postarray['target_domain'])) {
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $target_domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
- if ($postarray['alias_domain'] == $postarray['target_domain']) {
+ if ($alias_domain == $target_domain) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['aliasd_targetd_identical'])
);
return false;
}
- $alias_domain = strtolower(trim($postarray['alias_domain']));
- $target_domain = strtolower(trim($postarray['target_domain']));
-
try {
$stmt = $pdo->prepare("SELECT `domain` FROM `domain`
WHERE `domain`= :target_domain");
$stmt->execute(array(':target_domain' => $target_domain));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results == 0) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['targetd_not_found'])
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain`= :alias_domain
UNION
SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain`= :alias_domain_in_domain");
$stmt->execute(array(':alias_domain' => $alias_domain, ':alias_domain_in_domain' => $alias_domain));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results != 0) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['aliasd_exists'])
);
return false;
}
try {
$stmt = $pdo->prepare("INSERT INTO `alias_domain` (`alias_domain`, `target_domain`, `created`, `modified`, `active`)
VALUES (:alias_domain, :target_domain, :created, :modified, :active)");
$stmt->execute(array(
':alias_domain' => $alias_domain,
':target_domain' => $target_domain,
':created' => date('Y-m-d H:i:s'),
':modified' => date('Y-m-d H:i:s'),
':active' => $active
));
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['aliasd_added'], htmlspecialchars($alias_domain))
);
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
function mailbox_edit_alias_domain($postarray) {
+ // Array elements
+ // active int
+ // alias_domain_now string
+ // alias_domain string
global $lang;
global $pdo;
isset($postarray['active']) ? $active = '1' : $active = '0';
- $alias_domain = idn_to_ascii($postarray['alias_domain']);
- $alias_domain = strtolower(trim($alias_domain));
- $alias_domain_now = strtolower(trim($postarray['alias_domain_now']));
+ $alias_domain = idn_to_ascii(strtolower(trim($postarray['alias_domain'])));
+ $alias_domain_now = strtolower(trim($postarray['alias_domain_now']));
if (!is_valid_domain_name($alias_domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['alias_domain_invalid'])
);
return false;
}
if (!is_valid_domain_name($alias_domain_now)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['alias_domain_invalid'])
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
WHERE `alias_domain`= :alias_domain_now");
$stmt->execute(array(':alias_domain_now' => $alias_domain_now));
$DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $DomainData['target_domain'])) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
WHERE `target_domain`= :alias_domain");
$stmt->execute(array(':alias_domain' => $alias_domain));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results != 0) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['aliasd_targetd_identical'])
);
return false;
}
try {
$stmt = $pdo->prepare("UPDATE `alias_domain` SET `alias_domain` = :alias_domain, `active` = :active WHERE `alias_domain` = :alias_domain_now");
$stmt->execute(array(
':alias_domain' => $alias_domain,
':alias_domain_now' => $alias_domain_now,
':active' => $active
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['aliasd_modified'], htmlspecialchars($alias_domain))
);
}
function mailbox_add_mailbox($postarray) {
+ // Array elements
+ // active int
+ // local_part string
+ // domain string
+ // name string (username if empty)
+ // password string
+ // password2 string
+ // quota int (MiB)
+ // active int
+
global $pdo;
global $lang;
- $username = strtolower(trim($postarray['local_part'])).'@'.strtolower(trim($postarray['domain']));
+ $local_part = strtolower(trim($postarray['local_part']));
+ $domain = idn_to_ascii(strtolower(trim($postarray['domain'])));
+ $username = $local_part . '@' . $domain;
if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['mailbox_invalid'])
);
return false;
}
if (empty($postarray['local_part'])) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['mailbox_invalid'])
);
return false;
}
- $domain = strtolower(trim($postarray['domain']));
- $password = $postarray['password'];
- $password2 = $postarray['password2'];
- $local_part = strtolower(trim($postarray['local_part']));
- $name = $postarray['name'];
- $quota_m = $postarray['quota'];
+ $password = $postarray['password'];
+ $password2 = $postarray['password2'];
+ $name = $postarray['name'];
+ $quota_m = filter_var($postarray['quota'], FILTER_SANITIZE_NUMBER_FLOAT);
if (empty($name)) {
$name = $local_part;
}
isset($postarray['active']) ? $active = '1' : $active = '0';
$quota_b = ($quota_m * 1048576);
$maildir = $domain."/".$local_part."/";
if (!is_valid_domain_name($domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['domain_invalid'])
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `mailboxes`, `maxquota`, `quota` FROM `domain`
WHERE `domain` = :domain");
$stmt->execute(array(':domain' => $domain));
$DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT
COUNT(*) as count,
COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota`
FROM `mailbox`
WHERE `domain` = :domain");
$stmt->execute(array(':domain' => $domain));
$MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `local_part` FROM `mailbox` WHERE `local_part` = :local_part and `domain`= :domain");
$stmt->execute(array(':local_part' => $local_part, ':domain' => $domain));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results != 0) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($username))
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE address= :username");
$stmt->execute(array(':username' => $username));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results != 0) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['is_alias'], htmlspecialchars($username))
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `address` FROM `spamalias` WHERE `address`= :username");
$stmt->execute(array(':username' => $username));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results != 0) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($username))
);
return false;
}
if (!is_numeric($quota_m) || $quota_m == "0") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['quota_not_0_not_numeric'])
);
return false;
}
if (!empty($password) && !empty($password2)) {
if ($password != $password2) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['password_mismatch'])
);
return false;
}
$password_hashed = hash_password($password);
}
else {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['password_empty'])
);
return false;
}
if ($MailboxData['count'] >= $DomainData['mailboxes']) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['max_mailbox_exceeded'], $MailboxData['count'], $DomainData['mailboxes'])
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `domain` FROM `domain` WHERE `domain`= :domain");
$stmt->execute(array(':domain' => $domain));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results == 0) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => $lang['danger']['domain_not_found']
+ 'msg' => sprintf($lang['danger']['domain_not_found'], $domain)
);
return false;
}
if ($quota_m > $DomainData['maxquota']) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['mailbox_quota_exceeded'], $DomainData['maxquota'])
);
return false;
}
if (($MailboxData['quota'] + $quota_m) > $DomainData['quota']) {
$quota_left_m = ($DomainData['quota'] - $MailboxData['quota']);
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['mailbox_quota_left_exceeded'], $quota_left_m)
);
return false;
}
try {
$stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `created`, `modified`, `active`)
VALUES (:username, :password_hashed, :name, :maildir, :quota_b, :local_part, :domain, :created, :modified, :active)");
$stmt->execute(array(
':username' => $username,
':password_hashed' => $password_hashed,
':name' => $name,
':maildir' => $maildir,
':quota_b' => $quota_b,
':local_part' => $local_part,
':domain' => $domain,
':created' => date('Y-m-d H:i:s'),
':modified' => date('Y-m-d H:i:s'),
':active' => $active
));
$stmt = $pdo->prepare("INSERT INTO `quota2` (`username`, `bytes`, `messages`)
VALUES (:username, '0', '0')");
$stmt->execute(array(':username' => $username));
$stmt = $pdo->prepare("INSERT INTO `alias` (`address`, `goto`, `domain`, `created`, `modified`, `active`)
VALUES (:username1, :username2, :domain, :created, :modified, :active)");
$stmt->execute(array(
':username1' => $username,
':username2' => $username,
':domain' => $domain,
':created' => date('Y-m-d H:i:s'),
':modified' => date('Y-m-d H:i:s'),
':active' => $active
));
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_added'], htmlspecialchars($username))
);
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
function mailbox_edit_alias($postarray) {
+ // Array elements
+ // address string
+ // goto string (separated by " ", "," ";" "\n") - email address or domain
+ // active int
global $lang;
global $pdo;
- $address = $postarray['address'];
- $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
- $local_part = strstr($address, '@', true);
+ $address = $postarray['address'];
+ $domain = idn_to_ascii(substr(strstr($address, '@'), 1));
+ $local_part = strstr($address, '@', true);
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if (empty($postarray['goto'])) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['goto_empty'])
);
return false;
}
$gotos = array_map('trim', preg_split( "/( |,|;|\n)/", $postarray['goto']));
foreach ($gotos as &$goto) {
if (empty($goto)) {
continue;
}
if (!filter_var($goto, FILTER_VALIDATE_EMAIL)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' =>sprintf($lang['danger']['goto_invalid'])
);
return false;
}
if ($goto == $address) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['alias_goto_identical'])
);
return false;
}
}
$gotos = array_filter($gotos);
$goto = implode(",", $gotos);
isset($postarray['active']) ? $active = '1' : $active = '0';
if ((!filter_var($address, FILTER_VALIDATE_EMAIL) === true) && !empty($local_part)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['alias_invalid'])
);
return false;
}
try {
$stmt = $pdo->prepare("UPDATE `alias` SET `goto` = :goto, `active`= :active WHERE `address` = :address");
$stmt->execute(array(
':goto' => $goto,
':active' => $active,
':address' => $address
));
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['alias_modified'], htmlspecialchars($address))
);
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
function mailbox_edit_domain($postarray) {
+ // Array elements
+ // domain string
+ // description string
+ // active int
+ // relay_all_recipients int
+ // backupmx int
+ // aliases float
+ // mailboxes float
+ // maxquota float
+ // quota float (Byte)
+ // active int
+
global $lang;
global $pdo;
- $domain = $postarray['domain'];
- $description = $postarray['description'];
+ $domain = idn_to_ascii($postarray['domain']);
+ $description = $postarray['description'];
$aliases = filter_var($postarray['aliases'], FILTER_SANITIZE_NUMBER_FLOAT);
- $mailboxes = filter_var($postarray['mailboxes'], FILTER_SANITIZE_NUMBER_FLOAT);
+ $mailboxes = filter_var($postarray['mailboxes'], FILTER_SANITIZE_NUMBER_FLOAT);
$maxquota = filter_var($postarray['maxquota'], FILTER_SANITIZE_NUMBER_FLOAT);
$quota = filter_var($postarray['quota'], FILTER_SANITIZE_NUMBER_FLOAT);
isset($postarray['relay_all_recipients']) ? $relay_all_recipients = '1' : $relay_all_recipients = '0';
isset($postarray['backupmx']) ? $backupmx = '1' : $backupmx = '0';
isset($postarray['relay_all_recipients']) ? $backupmx = '1' : true;
isset($postarray['active']) ? $active = '1' : $active = '0';
try {
$stmt = $pdo->prepare("SELECT
COUNT(*) AS count,
MAX(COALESCE(ROUND(`quota`/1048576), 0)) AS `maxquota`,
COALESCE(ROUND(SUM(`quota`)/1048576), 0) AS `quota`
FROM `mailbox`
WHERE domain= :domain");
$stmt->execute(array(':domain' => $domain));
$MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT COUNT(*) AS `count` FROM `alias`
WHERE domain = :domain
AND address NOT IN (
SELECT `username` FROM `mailbox`
)");
$stmt->execute(array(':domain' => $domain));
$AliasData = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if ($maxquota > $quota) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['mailbox_quota_exceeds_domain_quota'])
);
return false;
}
if ($MailboxData['maxquota'] > $maxquota) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['max_quota_in_use'], $MailboxData['maxquota'])
);
return false;
}
if ($MailboxData['quota'] > $quota) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['domain_quota_m_in_use'], $MailboxData['quota'])
);
return false;
}
if ($MailboxData['count'] > $mailboxes) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['mailboxes_in_use'], $MailboxData['count'])
);
return false;
}
if ($AliasData['count'] > $aliases) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['aliases_in_use'], $AliasData['count'])
);
return false;
}
if (!is_valid_domain_name($domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['domain_invalid'])
);
return false;
}
try {
$stmt = $pdo->prepare("UPDATE `domain` SET
`modified`= :modified,
`relay_all_recipients` = :relay_all_recipients,
`backupmx` = :backupmx,
`active` = :active,
`quota` = :quota,
`maxquota` = :maxquota,
`mailboxes` = :mailboxes,
`aliases` = :aliases,
`description` = :description
WHERE `domain` = :domain");
$stmt->execute(array(
':relay_all_recipients' => $relay_all_recipients,
':backupmx' => $backupmx,
':active' => $active,
':quota' => $quota,
':maxquota' => $maxquota,
':mailboxes' => $mailboxes,
':aliases' => $aliases,
':modified' => date('Y-m-d H:i:s'),
':description' => $description,
':domain' => $domain
));
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['domain_modified'], htmlspecialchars($domain))
);
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
-function edit_domain_admin($postarray) {
+function mailbox_get_mailboxes($domain) {
global $lang;
global $pdo;
- $username = $postarray['username'];
- $password = $postarray['password'];
- $password2 = $postarray['password2'];
- isset($postarray['active']) ? $active = '1' : $active = '0';
-
- if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $mailboxes = array();
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
-
- foreach ($postarray['domain'] as $domain) {
- if (!is_valid_domain_name($domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
+ try {
+ $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `domain` != 'ALL' AND `domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $mailboxes[] = $row['username'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ return $mailboxes;
+}
+function mailbox_get_alias_domains($domain) {
+ global $lang;
+ global $pdo;
+ $aliasdomains = array();
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
}
- if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
+ try {
+ $stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $aliasdomains[] = $row['alias_domain'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ return $aliasdomains;
+}
+function mailbox_get_aliases($domain) {
+ global $lang;
+ global $pdo;
+ $aliases = array();
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => sprintf($lang['danger']['username_invalid'])
+ 'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
- try {
- $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
- $stmt->execute(array(
- ':username' => $username,
- ));
- }
- catch (PDOException $e) {
+ try {
+ $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `address` != `goto` AND `domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $aliases[] = $row['address'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ return $aliases;
+}
+function mailbox_get_alias_details($address) {
+ global $lang;
+ global $pdo;
+ $aliasdata = array();
+ try {
+ $stmt = $pdo->prepare("SELECT
+ `domain`,
+ `goto`,
+ `address`,
+ CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
+ `created`,
+ `modified`
+ FROM `alias`
+ WHERE `address` = :address AND `address` != `goto`");
+ $stmt->execute(array(
+ ':address' => $address,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $aliasdata['domain'] = $row['domain'];
+ $aliasdata['goto'] = $row['goto'];
+ $aliasdata['address'] = $row['address'];
+ (!filter_var($aliasdata['address'], FILTER_VALIDATE_EMAIL)) ? $aliasdata['is_catch_all'] = 1 : $aliasdata['is_catch_all'] = 0;
+ $aliasdata['active'] = $row['active'];
+ $aliasdata['created'] = $row['created'];
+ $aliasdata['modified'] = $row['modified'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if (isset($aliasdata['domain']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $aliasdata['domain'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ return $aliasdata;
+}
+function mailbox_get_alias_domain_details($aliasdomain) {
+ global $lang;
+ global $pdo;
+ $aliasdomaindata = array();
+ try {
+ $stmt = $pdo->prepare("SELECT
+ `alias_domain`,
+ `target_domain`,
+ CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
+ `created`,
+ `modified`
+ FROM `alias_domain`
+ WHERE `alias_domain` = :aliasdomain");
+ $stmt->execute(array(
+ ':aliasdomain' => $aliasdomain,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $aliasdomaindata['alias_domain'] = $row['alias_domain'];
+ $aliasdomaindata['target_domain'] = $row['target_domain'];
+ $aliasdomaindata['active'] = $row['active'];
+ $aliasdomaindata['created'] = $row['created'];
+ $aliasdomaindata['modified'] = $row['modified'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if (isset($aliasdomaindata['target_domain']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $aliasdomaindata['target_domain'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ return $aliasdomaindata;
+}
+function mailbox_get_domains() {
+ global $lang;
+ global $pdo;
+
+ try {
+ $domains = array();
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
+ WHERE (`domain` IN (
+ SELECT `domain` from `domain_admins`
+ WHERE (`active`='1' AND `username` = :username))
+ )
+ OR ('admin'= :role)
+ AND `domain` != 'ALL'");
+ $stmt->execute(array(
+ ':username' => $_SESSION['mailcow_cc_username'],
+ ':role' => $_SESSION['mailcow_cc_role'],
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $domains[] = $row['domain'];
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ return $domains;
+}
+function mailbox_get_domain_details($domain) {
+ global $lang;
+ global $pdo;
+
+ $domain = idn_to_ascii(strtolower(trim($domain)));
+
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
- 'msg' => 'MySQL: '.$e
+ 'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
- foreach ($postarray['domain'] as $domain) {
- try {
- $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
- VALUES (:username, :domain, :created, :active)");
- $stmt->execute(array(
- ':username' => $username,
- ':domain' => $domain,
- ':created' => date('Y-m-d H:i:s'),
- ':active' => $active
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
+ try {
+ $stmt = $pdo->prepare("SELECT
+ `domain`,
+ `aliases`,
+ `mailboxes`,
+ `maxquota`,
+ `quota`,
+ CASE `backupmx` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `backupmx`,
+ CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
+ FROM `domain` WHERE `domain`= :domain");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $domaindata['domain_name'] = $row['domain'];
+ $domaindata['max_num_aliases_for_domain'] = $row['aliases'];
+ $domaindata['max_num_mboxes_for_domain'] = $row['mailboxes'];
+ $domaindata['max_quota_for_mbox'] = formatBytes(intval($row['maxquota'] * 1048576), 2);
+ $domaindata['max_quota_for_domain'] = formatBytes(intval($row['quota'] * 1048576), 2);
+ $domaindata['backupmx'] = $row['backupmx'];
+ $domaindata['active'] = $row['active'];
+ }
- if (!empty($password) && !empty($password2)) {
- if ($password != $password2) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_mismatch'])
- );
- return false;
- }
- $password_hashed = hash_password($password);
- try {
- $stmt = $pdo->prepare("UPDATE `admin` SET `modified` = :modified, `active` = :active, `password` = :password_hashed WHERE `username` = :username");
- $stmt->execute(array(
- ':password_hashed' => $password_hashed,
- ':username' => $username,
- ':modified' => date('Y-m-d H:i:s'),
- ':active' => $active
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- else {
- try {
- $stmt = $pdo->prepare("UPDATE `admin` SET `modified` = :modified, `active` = :active WHERE `username` = :username");
- $stmt->execute(array(
- ':username' => $username,
- ':modified' => date('Y-m-d H:i:s'),
- ':active' => $active
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
+ $stmt = $pdo->prepare("SELECT COUNT(*) AS `alias_count` FROM `alias`
+ WHERE `domain`= :domain
+ AND `address` NOT IN (
+ SELECT `username` FROM `mailbox`
+ )");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ));
+ $row = $stmt->fetchAll();
+ $domaindata['aliases_in_domain'] = $row[0]['alias_count'];
+
+ $stmt = $pdo->prepare("SELECT COUNT(`username`) AS `mailbox_count`, SUM(`quota`) AS `quota` FROM `mailbox`
+ WHERE `domain` = :domain");
+ $stmt->execute(array(
+ ':domain' => $domain,
+ ));
+ $row = $stmt->fetchAll();
+ $domaindata['mboxes_in_domain'] = $row[0]['mailbox_count'];
+ $domaindata['quota_used_in_domain'] = formatBytes(intval($row[0]['quota']), 2);
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_admin_modified'], htmlspecialchars($username))
- );
+ return $domaindata;
+}
+function mailbox_get_mailbox_details($mailbox) {
+ global $lang;
+ global $pdo;
+ try {
+ $stmt = $pdo->prepare("SELECT
+ `domain`.`backupmx`,
+ `mailbox`.`username`,
+ `mailbox`.`name`,
+ CASE `mailbox`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
+ `mailbox`.`domain`,
+ `mailbox`.`quota`,
+ `quota2`.`bytes`,
+ `quota2`.`messages`
+ FROM `mailbox`, `quota2`, `domain`
+ WHERE `mailbox`.`username` = `quota2`.`username` AND `domain`.`domain` = `mailbox`.`domain` AND `mailbox`.`username` = :mailbox");
+ $stmt->execute(array(
+ ':mailbox' => $mailbox,
+ ));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $mailboxdata['username'] = $row['username'];
+ $mailboxdata['is_relayed'] = $row['backupmx'];
+ $mailboxdata['name'] = $row['name'];
+ $mailboxdata['active'] = $row['active'];
+ $mailboxdata['domain'] = $row['domain'];
+ $mailboxdata['quota'] = formatBytes(intval($row['quota']), 2);
+ $mailboxdata['quota_used'] = formatBytes(intval($row['bytes']), 2);
+ $mailboxdata['percent_in_use'] = round((intval($row['bytes']) / intval($row['quota'])) * 100);
+ $mailboxdata['messages'] = $row['messages'];
+ if ($mailboxdata['percent_in_use'] >= 90) {
+ $mailboxdata['percent_class'] = "danger";
+ }
+ elseif ($mailboxdata['percent_in_use'] >= 75) {
+ $mailboxdata['percent_class'] = "warning";
+ }
+ else {
+ $mailboxdata['percent_class'] = "success";
+ }
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if (isset($mailboxdata['domain']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $mailboxdata['domain'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ return $mailboxdata;
}
function mailbox_edit_mailbox($postarray) {
global $lang;
global $pdo;
isset($postarray['active']) ? $active = '1' : $active = '0';
if (!filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['username_invalid'])
);
return false;
}
$quota_m = $postarray['quota'];
$quota_b = $quota_m*1048576;
$username = $postarray['username'];
$name = $postarray['name'];
$password = $postarray['password'];
$password2 = $postarray['password2'];
try {
$stmt = $pdo->prepare("SELECT `domain`
FROM `mailbox`
WHERE username = :username");
$stmt->execute(array(':username' => $username));
$MailboxData1 = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt = $pdo->prepare("SELECT
COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota_m_now`
FROM `mailbox`
WHERE `username` = :username");
$stmt->execute(array(':username' => $username));
$MailboxData2 = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt = $pdo->prepare("SELECT
COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota_m_in_use`
FROM `mailbox`
WHERE `domain` = :domain");
$stmt->execute(array(':domain' => $MailboxData1['domain']));
$MailboxData3 = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt = $pdo->prepare("SELECT `quota`, `maxquota`
FROM `domain`
WHERE `domain` = :domain");
$stmt->execute(array(':domain' => $MailboxData1['domain']));
$DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $MailboxData1['domain'])) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if (!is_numeric($quota_m) || $quota_m == "0") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['quota_not_0_not_numeric'], htmlspecialchars($quota_m))
);
return false;
}
if ($quota_m > $DomainData['maxquota']) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['mailbox_quota_exceeded'], $DomainData['maxquota'])
);
return false;
}
if (($MailboxData3['quota_m_in_use'] - $MailboxData2['quota_m_now'] + $quota_m) > $DomainData['quota']) {
$quota_left_m = ($DomainData['quota'] - $MailboxData3['quota_m_in_use'] + $MailboxData2['quota_m_now']);
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['mailbox_quota_left_exceeded'], $quota_left_m)
);
return false;
}
try {
$stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
$stmt->execute(array(
':username' => $username
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if (isset($postarray['sender_acl']) && is_array($postarray['sender_acl'])) {
foreach ($postarray['sender_acl'] as $sender_acl) {
if (!filter_var($sender_acl, FILTER_VALIDATE_EMAIL) &&
!is_valid_domain_name(str_replace('@', '', $sender_acl))) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['sender_acl_invalid'])
);
return false;
}
}
foreach ($postarray['sender_acl'] as $sender_acl) {
try {
$stmt = $pdo->prepare("INSERT INTO `sender_acl` (`send_as`, `logged_in_as`)
VALUES (:sender_acl, :username)");
$stmt->execute(array(
':sender_acl' => $sender_acl,
':username' => $username
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
}
if (!empty($password) && !empty($password2)) {
if ($password != $password2) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['password_mismatch'])
);
return false;
}
$password_hashed = hash_password($password);
try {
$stmt = $pdo->prepare("UPDATE `alias` SET
`modified` = :modified,
`active` = :active
WHERE `address` = :address");
$stmt->execute(array(
':address' => $username,
':modified' => date('Y-m-d H:i:s'),
':active' => $active
));
$stmt = $pdo->prepare("UPDATE `mailbox` SET
`modified` = :modified,
`active` = :active,
`password` = :password_hashed,
`name`= :name,
`quota` = :quota_b
WHERE `username` = :username");
$stmt->execute(array(
':modified' => date('Y-m-d H:i:s'),
':password_hashed' => $password_hashed,
':active' => $active,
':name' => $name,
':quota_b' => $quota_b,
':username' => $username
));
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], $username)
);
return true;
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
try {
$stmt = $pdo->prepare("UPDATE `alias` SET
`modified` = :modified,
`active` = :active
WHERE `address` = :address");
$stmt->execute(array(
':address' => $username,
':modified' => date('Y-m-d H:i:s'),
':active' => $active
));
$stmt = $pdo->prepare("UPDATE `mailbox` SET
`modified` = :modified,
`active` = :active,
`name`= :name,
`quota` = :quota_b
WHERE `username` = :username");
$stmt->execute(array(
':active' => $active,
':modified' => date('Y-m-d H:i:s'),
':name' => $name,
':quota_b' => $quota_b,
':username' => $username
));
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], $username)
);
return true;
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
function mailbox_delete_domain($postarray) {
global $lang;
global $pdo;
$domain = $postarray['domain'];
if ($_SESSION['mailcow_cc_role'] != "admin") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if (!is_valid_domain_name($domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['domain_invalid'])
);
return false;
}
$domain = strtolower(trim($domain));
try {
$stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
WHERE `domain` = :domain");
$stmt->execute(array(':domain' => $domain));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results != 0 || !empty($num_results)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['domain_not_empty'])
);
return false;
}
try {
$stmt = $pdo->prepare("DELETE FROM `domain` WHERE `domain` = :domain");
$stmt->execute(array(
':domain' => $domain,
));
$stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `domain` = :domain");
$stmt->execute(array(
':domain' => $domain,
));
$stmt = $pdo->prepare("DELETE FROM `alias` WHERE `domain` = :domain");
$stmt->execute(array(
':domain' => $domain,
));
$stmt = $pdo->prepare("DELETE FROM `alias_domain` WHERE `target_domain` = :domain");
$stmt->execute(array(
':domain' => $domain,
));
$stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `domain` = :domain");
$stmt->execute(array(
':domain' => $domain,
));
$stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` LIKE :domain");
$stmt->execute(array(
':domain' => '%@'.$domain,
));
$stmt = $pdo->prepare("DELETE FROM `quota2` WHERE `username` = :domain");
$stmt->execute(array(
':domain' => '%@'.$domain,
));
$stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `address` = :domain");
$stmt->execute(array(
':domain' => '%@'.$domain,
));
$stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :domain");
$stmt->execute(array(
':domain' => '%@'.$domain,
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['domain_removed'], htmlspecialchars($domain))
);
return true;
}
function mailbox_delete_alias($postarray) {
global $lang;
global $pdo;
$address = $postarray['address'];
$local_part = strstr($address, '@', true);
$domain = substr(strrchr($address, "@"), 1);
try {
$stmt = $pdo->prepare("SELECT `goto` FROM `alias` WHERE `address` = :address");
$stmt->execute(array(':address' => $address));
$gotos = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$goto_array = explode(',', $gotos['goto']);
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
try {
$stmt = $pdo->prepare("DELETE FROM `alias` WHERE `address` = :address AND `address` NOT IN (SELECT `username` FROM `mailbox`)");
$stmt->execute(array(
':address' => $address
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['alias_removed'], htmlspecialchars($address))
);
}
function mailbox_delete_alias_domain($postarray) {
global $lang;
global $pdo;
if (!is_valid_domain_name($postarray['alias_domain'])) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['domain_invalid'])
);
return false;
}
$alias_domain = $postarray['alias_domain'];
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
);
return false;
}
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $DomainData['target_domain'])) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
try {
$stmt = $pdo->prepare("DELETE FROM `alias_domain` WHERE `alias_domain` = :alias_domain");
$stmt->execute(array(
':alias_domain' => $alias_domain,
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['alias_domain_removed'], htmlspecialchars($alias_domain))
);
}
function mailbox_delete_mailbox($postarray) {
global $lang;
global $pdo;
$domain = substr(strrchr($postarray['username'], "@"), 1);
$username = $postarray['username'];
if (!filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
try {
$stmt = $pdo->prepare("DELETE FROM `alias` WHERE `goto` = :username");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("DELETE FROM `quota2` WHERE `username` = :username");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `username` = :username");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("DELETE FROM `sender_acl` WHERE `logged_in_as` = :username");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("SELECT `address`, `goto` FROM `alias`
WHERE `goto` LIKE :username");
$stmt->execute(array(':username' => '%'.$username.'%'));
$GotoData = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($GotoData as $gotos) {
$goto_exploded = explode(',', $gotos['goto']);
if (($key = array_search($username, $goto_exploded)) !== false) {
unset($goto_exploded[$key]);
}
$gotos_rebuild = implode(',', $goto_exploded);
$stmt = $pdo->prepare("UPDATE `alias` SET `goto` = :goto WHERE `address` = :address");
$stmt->execute(array(
':goto' => $gotos_rebuild,
':address' => $gotos['address']
));
}
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_removed'], htmlspecialchars($username))
);
}
+function edit_domain_admin($postarray) {
+ global $lang;
+ global $pdo;
+ $username = $postarray['username'];
+ $password = $postarray['password'];
+ $password2 = $postarray['password2'];
+ isset($postarray['active']) ? $active = '1' : $active = '0';
+
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+
+ foreach ($postarray['domain'] as $domain) {
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ }
+
+ if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username,
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+
+ foreach ($postarray['domain'] as $domain) {
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
+ VALUES (:username, :domain, :created, :active)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':domain' => $domain,
+ ':created' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+
+ if (!empty($password) && !empty($password2)) {
+ if ($password != $password2) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_mismatch'])
+ );
+ return false;
+ }
+ $password_hashed = hash_password($password);
+ try {
+ $stmt = $pdo->prepare("UPDATE `admin` SET `modified` = :modified, `active` = :active, `password` = :password_hashed WHERE `username` = :username");
+ $stmt->execute(array(
+ ':password_hashed' => $password_hashed,
+ ':username' => $username,
+ ':modified' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ else {
+ try {
+ $stmt = $pdo->prepare("UPDATE `admin` SET `modified` = :modified, `active` = :active WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':modified' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_admin_modified'], htmlspecialchars($username))
+ );
+}
function set_admin_account($postarray) {
global $lang;
global $pdo;
if ($_SESSION['mailcow_cc_role'] != "admin") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
$name = $postarray['admin_user'];
$name_now = $postarray['admin_user_now'];
if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $name)) || empty ($name)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['username_invalid'])
);
return false;
}
if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $name_now)) || empty ($name_now)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['username_invalid'])
);
return false;
}
if (!empty($postarray['admin_pass']) && !empty($postarray['admin_pass2'])) {
if ($postarray['admin_pass'] != $postarray['admin_pass2']) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['password_mismatch'])
);
return false;
}
$password_hashed = hash_password($postarray['admin_pass']);
try {
$stmt = $pdo->prepare("UPDATE `admin` SET
`modified` = :modified,
`password` = :password_hashed,
`username` = :name
WHERE `username` = :username");
$stmt->execute(array(
':password_hashed' => $password_hashed,
':modified' => date('Y-m-d H:i:s'),
':name' => $name,
':username' => $name_now
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
else {
try {
$stmt = $pdo->prepare("UPDATE `admin` SET
`modified` = :modified,
`username` = :name
WHERE `username` = :name_now");
$stmt->execute(array(
':name' => $name,
':modified' => date('Y-m-d H:i:s'),
':name_now' => $name_now
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
try {
$stmt = $pdo->prepare("UPDATE `domain_admins` SET
`domain` = :domain,
`username` = :name
WHERE `username` = :name_now");
$stmt->execute(array(
':domain' => 'ALL',
':name' => $name,
':name_now' => $name_now
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['admin_modified'])
);
}
function set_time_limited_aliases($postarray) {
global $lang;
global $pdo;
$username = $_SESSION['mailcow_cc_username'];
- $domain = substr($username, strpos($username, '@'));
- if (($_SESSION['mailcow_cc_role'] != "user" &&
- $_SESSION['mailcow_cc_role'] != "domainadmin") ||
- empty($username) ||
- empty($domain)) {
+ try {
+ $stmt = $pdo->prepare("SELECT `domain` FROM `mailbox` WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ $domain = $stmt->fetch(PDO::FETCH_ASSOC)['domain'];
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ if ($_SESSION['mailcow_cc_role'] != "user" || empty($username) || empty($domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
switch ($postarray["trigger_set_time_limited_aliases"]) {
case "generate":
if (!is_numeric($postarray["validity"]) || $postarray["validity"] > 672) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['validity_missing'])
);
return false;
}
$validity = strtotime("+".$postarray["validity"]." hour");
$letters = 'abcefghijklmnopqrstuvwxyz1234567890';
$random_name = substr(str_shuffle($letters), 0, 24);
try {
$stmt = $pdo->prepare("INSERT INTO `spamalias` (`address`, `goto`, `validity`) VALUES
(:address, :goto, :validity)");
$stmt->execute(array(
- ':address' => $random_name.$domain,
+ ':address' => $random_name . '@' . $domain,
':goto' => $username,
':validity' => $validity
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
);
break;
- case "delete":
+ case "deleteall":
try {
$stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username");
$stmt->execute(array(
':username' => $username
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
);
break;
+ case "delete":
+ if (empty($postarray['item']) || !filter_var($postarray['item'], FILTER_VALIDATE_EMAIL)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ $item = $postarray['item'];
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `spamalias` WHERE `goto` = :username AND `address` = :item");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':item' => $item
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
+ );
+ break;
case "extend":
try {
$stmt = $pdo->prepare("UPDATE `spamalias` SET `validity` = (`validity` + 3600)
WHERE `goto` = :username
AND `validity` >= :validity");
$stmt->execute(array(
':username' => $username,
':validity' => time(),
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
);
break;
}
}
function set_user_account($postarray) {
global $lang;
global $pdo;
$username = $_SESSION['mailcow_cc_username'];
$password_old = $postarray['user_old_pass'];
isset($postarray['togglePwNew']) ? $pwnew_active = '1' : $pwnew_active = '0';
if (isset($pwnew_active) && $pwnew_active == "1") {
$password_new = $postarray['user_new_pass'];
$password_new2 = $postarray['user_new_pass2'];
}
if (!check_login($username, $password_old) == "user") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if ($_SESSION['mailcow_cc_role'] != "user" &&
$_SESSION['mailcow_cc_role'] != "domainadmin") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if (isset($password_new) && isset($password_new2)) {
if (!empty($password_new2) && !empty($password_new)) {
if ($password_new2 != $password_new) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['password_mismatch'])
);
return false;
}
if (strlen($password_new) < "6" ||
!preg_match('/[A-Za-z]/', $password_new) ||
!preg_match('/[0-9]/', $password_new)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['password_complexity'])
);
return false;
}
$password_hashed = hash_password($password_new);
try {
$stmt = $pdo->prepare("UPDATE `mailbox` SET `modified` = :modified, `password` = :password_hashed WHERE `username` = :username");
$stmt->execute(array(
':password_hashed' => $password_hashed,
':modified' => date('Y-m-d H:i:s'),
':username' => $username
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], $username)
);
}
function add_domain_admin($postarray) {
global $lang;
global $pdo;
$username = strtolower(trim($postarray['username']));
$password = $postarray['password'];
$password2 = $postarray['password2'];
isset($postarray['active']) ? $active = '1' : $active = '0';
if ($_SESSION['mailcow_cc_role'] != "admin") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if (empty($postarray['domain'])) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['domain_invalid'])
);
return false;
}
if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username)) || empty ($username)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['username_invalid'])
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
WHERE `username` = :username");
$stmt->execute(array(':username' => $username));
$num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
$stmt = $pdo->prepare("SELECT `username` FROM `admin`
WHERE `username` = :username");
$stmt->execute(array(':username' => $username));
$num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
$stmt = $pdo->prepare("SELECT `username` FROM `domain_admins`
WHERE `username` = :username");
$stmt->execute(array(':username' => $username));
$num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
foreach ($num_results as $num_results_each) {
if ($num_results_each != 0) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($username))
);
return false;
}
}
if (!empty($password) && !empty($password2)) {
if ($password != $password2) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['password_mismatch'])
);
return false;
}
$password_hashed = hash_password($password);
foreach ($postarray['domain'] as $domain) {
if (!is_valid_domain_name($domain)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['domain_invalid'])
);
return false;
}
try {
$stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
VALUES (:username, :domain, :created, :active)");
$stmt->execute(array(
':username' => $username,
':domain' => $domain,
':created' => date('Y-m-d H:i:s'),
':active' => $active
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
try {
$stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `created`, `modified`, `active`)
VALUES (:username, :password_hashed, '0', :created, :modified, :active)");
$stmt->execute(array(
':username' => $username,
':password_hashed' => $password_hashed,
':created' => date('Y-m-d H:i:s'),
':modified' => date('Y-m-d H:i:s'),
':active' => $active
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
else {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['password_empty'])
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['domain_admin_added'], htmlspecialchars($username))
);
}
function delete_domain_admin($postarray) {
global $pdo;
global $lang;
if ($_SESSION['mailcow_cc_role'] != "admin") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
$username = $postarray['username'];
if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['username_invalid'])
);
return false;
}
try {
$stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
$stmt->execute(array(
':username' => $username,
));
$stmt = $pdo->prepare("DELETE FROM `admin` WHERE `username` = :username");
$stmt->execute(array(
':username' => $username,
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['domain_admin_removed'], htmlspecialchars($username))
);
}
function get_spam_score($username) {
global $pdo;
$default = "5, 15";
if ($_SESSION['mailcow_cc_role'] != "user") {
return false;
}
if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
return $default;
}
try {
$stmt = $pdo->prepare("SELECT `value` FROM `filterconf` WHERE `object` = :username AND
(`option` = 'lowspamlevel' OR `option` = 'highspamlevel')");
$stmt->execute(array(':username' => $username));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results == 0 || empty ($num_results)) {
return $default;
}
else {
try {
$stmt = $pdo->prepare("SELECT `value` FROM `filterconf` WHERE `option` = 'highspamlevel' AND `object` = :username");
$stmt->execute(array(':username' => $username));
$highspamlevel = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt = $pdo->prepare("SELECT `value` FROM `filterconf` WHERE `option` = 'lowspamlevel' AND `object` = :username");
$stmt->execute(array(':username' => $username));
$lowspamlevel = $stmt->fetch(PDO::FETCH_ASSOC);
return $lowspamlevel['value'].', '.$highspamlevel['value'];
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
}
}
function set_spam_score($postarray) {
global $lang;
global $pdo;
if ($_SESSION['mailcow_cc_role'] != "user") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
$username = $_SESSION['mailcow_cc_username'];
$lowspamlevel = explode(',', $postarray['score'])[0];
$highspamlevel = explode(',', $postarray['score'])[1];
if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['username_invalid'])
);
return false;
}
if (!is_numeric($lowspamlevel) || !is_numeric($highspamlevel)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
try {
$stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :username
AND (`option` = 'lowspamlevel' OR `option` = 'highspamlevel')");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option`, `value`)
VALUES (:username, 'highspamlevel', :highspamlevel)");
$stmt->execute(array(
':username' => $username,
':highspamlevel' => $highspamlevel
));
$stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option`, `value`)
VALUES (:username, 'lowspamlevel', :lowspamlevel)");
$stmt->execute(array(
':username' => $username,
':lowspamlevel' => $lowspamlevel
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], $username)
);
}
function set_policy_list($postarray) {
global $lang;
global $pdo;
if ($_SESSION['mailcow_cc_role'] != "admin" &&
$_SESSION['mailcow_cc_role'] != "domainadmin" &&
$_SESSION['mailcow_cc_role'] != "user") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
(isset($postarray['domain'])) ? $object = $postarray['domain'] : $object = $_SESSION['mailcow_cc_username'];
($postarray['object_list'] == "bl") ? $object_list = "blacklist_from" : $object_list = "whitelist_from";
$object_from = preg_replace('/\.+/', '.', rtrim(preg_replace("/\.\*/", "*", trim(strtolower($postarray['object_from']))), '.'));
if (!filter_var($object, FILTER_VALIDATE_EMAIL) && !is_valid_domain_name($object)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['username_invalid'])
);
return false;
}
if (is_valid_domain_name($object)) {
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
}
if (isset($postarray['prefid'])) {
if (!is_numeric($postarray['prefid'])) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
try {
$stmt = $pdo->prepare("DELETE FROM `filterconf` WHERE `object` = :object AND `prefid` = :prefid");
$stmt->execute(array(
':object' => $object,
':prefid' => $postarray['prefid']
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], $object)
);
return true;
}
if (!ctype_alnum(str_replace(array('@', '.', '-', '*'), '', $object_from))) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['policy_list_from_invalid'])
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `object` FROM `filterconf`
WHERE (`option` = 'whitelist_from' OR `option` = 'blacklist_from')
AND `object` = :object
AND `value` = :object_from");
$stmt->execute(array(':object' => $object, ':object_from' => $object_from));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results != 0) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['policy_list_from_exists'])
);
return false;
}
try {
$stmt = $pdo->prepare("INSERT INTO `filterconf` (`object`, `option` ,`value`)
VALUES (:object, :object_list, :object_from)");
$stmt->execute(array(
':object' => $object,
':object_list' => $object_list,
':object_from' => $object_from
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], $object)
);
}
function set_tls_policy($postarray) {
global $lang;
global $pdo;
if ($_SESSION['mailcow_cc_role'] != "user") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
isset($postarray['tls_in']) ? $tls_in = '1' : $tls_in = '0';
isset($postarray['tls_out']) ? $tls_out = '1' : $tls_out = '0';
$username = $_SESSION['mailcow_cc_username'];
if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['username_invalid'])
);
return false;
}
try {
$stmt = $pdo->prepare("UPDATE `mailbox` SET `tls_enforce_out` = :tls_out, `tls_enforce_in` = :tls_in WHERE `username` = :username");
$stmt->execute(array(
':tls_out' => $tls_out,
':tls_in' => $tls_in,
':username' => $username
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], $username)
);
}
function set_syncjob($postarray, $action) {
global $lang;
global $pdo;
$username = $_SESSION['mailcow_cc_username'];
if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if ($_SESSION['mailcow_cc_role'] != "user") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
// DELETE
if ($action == "delete") {
$id = $postarray['id'];
if (!is_numeric($id)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
try {
$stmt = $pdo->prepare("DELETE FROM `imapsync` WHERE `user2` = :username AND `id`= :id");
$stmt->execute(array(
':username' => $username,
':id' => $id,
));
}
catch (PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username))
);
return true;
}
+ // ADD
elseif ($action == "add") {
isset($postarray['active']) ? $active = '1' : $active = '0';
isset($postarray['delete2duplicates']) ? $delete2duplicates = '1' : $delete2duplicates = '0';
$port1 = $postarray['port1'];
$host1 = $postarray['host1'];
$password1 = $postarray['password1'];
$exclude = $postarray['exclude'];
+ $maxage = $postarray['maxage'];
+ $subfolder2 = $postarray['subfolder2'];
$user1 = $postarray['user1'];
$mins_interval = $postarray['mins_interval'];
$enc1 = $postarray['enc1'];
+ if (empty($subfolder2)) {
+ $subfolder2 = "";
+ }
+ if (empty($maxage)) {
+ $maxage = 0;
+ }
+
+ if (!filter_var($maxage, FILTER_VALIDATE_INT, array('options' => array('min_range' => 0, 'max_range' => 32767)))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
if (!filter_var($port1, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 65535)))) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if (!filter_var($mins_interval, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 3600)))) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if (!is_valid_domain_name($host1)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if ($enc1 != "TLS" && $enc1 != "SSL" && $enc1 != "PLAIN") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if (@preg_match("/" . $exclude . "/", null) === false) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `user2`, `user1` FROM `imapsync`
WHERE `user2` = :user2 AND `user1` = :user1");
$stmt->execute(array(':user1' => $user1, ':user2' => $username));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if ($num_results != 0) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($host1 . ' / ' . $user1))
);
return false;
}
try {
- $stmt = $pdo->prepare("INSERT INTO `imapsync` (`user2`, `exclude`, `host1`, `authmech1`, `user1`, `password1`, `mins_interval`, `port1`, `enc1`, `delete2duplicates`, `active`)
- VALUES (:user2, :exclude, :host1, :authmech1, :user1, :password1, :mins_interval, :port1, :enc1, :delete2duplicates, :active)");
+ $stmt = $pdo->prepare("INSERT INTO `imapsync` (`user2`, `exclude`, `maxage`, `subfolder2`, `host1`, `authmech1`, `user1`, `password1`, `mins_interval`, `port1`, `enc1`, `delete2duplicates`, `active`)
+ VALUES (:user2, :exclude, :maxage, :subfolder2, :host1, :authmech1, :user1, :password1, :mins_interval, :port1, :enc1, :delete2duplicates, :active)");
$stmt->execute(array(
':user2' => $username,
':exclude' => $exclude,
+ ':maxage' => $maxage,
+ ':subfolder2' => $subfolder2,
':host1' => $host1,
':authmech1' => 'PLAIN',
':user1' => $user1,
':password1' => $password1,
':mins_interval' => $mins_interval,
':port1' => $port1,
':enc1' => $enc1,
':delete2duplicates' => $delete2duplicates,
':active' => $active,
));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], $username)
);
return true;
}
+ // EDIT
elseif ($action == "edit") {
isset($postarray['active']) ? $active = '1' : $active = '0';
isset($postarray['delete2duplicates']) ? $delete2duplicates = '1' : $delete2duplicates = '0';
$id = $postarray['id'];
$port1 = $postarray['port1'];
$host1 = $postarray['host1'];
$password1 = $postarray['password1'];
$exclude = $postarray['exclude'];
+ $maxage = $postarray['maxage'];
+ $subfolder2 = $postarray['subfolder2'];
$user1 = $postarray['user1'];
$mins_interval = $postarray['mins_interval'];
$enc1 = $postarray['enc1'];
+
+ if (empty($subfolder2)) {
+ $subfolder2 = "";
+ }
+ if (empty($maxage)) {
+ $maxage = 0;
+ }
+
+ if (!filter_var($maxage, FILTER_VALIDATE_INT, array('options' => array('min_range' => 0, 'max_range' => 32767)))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
if (!filter_var($port1, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1, 'max_range' => 65535)))) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if (!filter_var($mins_interval, FILTER_VALIDATE_INT, array('options' => array('min_range' => 10, 'max_range' => 3600)))) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if (!is_valid_domain_name($host1)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if ($enc1 != "TLS" && $enc1 != "SSL" && $enc1 != "PLAIN") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
if (@preg_match("/" . $exclude . "/", null) === false) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `user2` FROM `imapsync`
WHERE `user2` = :user2 AND `id` = :id");
$stmt->execute(array(':user2' => $username, ':id' => $id));
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
if (empty($num_results)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
try {
- $stmt = $pdo->prepare("UPDATE `imapsync` set `exclude` = :exclude, `host1` = :host1, `user1` = :user1, `password1` = :password1, `mins_interval` = :mins_interval, `port1` = :port1, `enc1` = :enc1, `delete2duplicates` = :delete2duplicates, `active` = :active
+ $stmt = $pdo->prepare("UPDATE `imapsync` set `maxage` = :maxage, `subfolder2` = :subfolder2, `exclude` = :exclude, `host1` = :host1, `user1` = :user1, `password1` = :password1, `mins_interval` = :mins_interval, `port1` = :port1, `enc1` = :enc1, `delete2duplicates` = :delete2duplicates, `active` = :active
WHERE `user2` = :user2 AND `id` = :id");
$stmt->execute(array(
':user2' => $username,
':id' => $id,
':exclude' => $exclude,
+ ':maxage' => $maxage,
+ ':subfolder2' => $subfolder2,
':host1' => $host1,
':user1' => $user1,
':password1' => $password1,
':mins_interval' => $mins_interval,
':port1' => $port1,
':enc1' => $enc1,
':delete2duplicates' => $delete2duplicates,
':active' => $active,
));
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], $username)
);
return true;
}
}
function get_tls_policy($username) {
global $lang;
global $pdo;
if ($_SESSION['mailcow_cc_role'] != "user") {
return false;
}
if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['username_invalid'])
);
return false;
}
try {
$stmt = $pdo->prepare("SELECT `tls_enforce_out`, `tls_enforce_in` FROM `mailbox` WHERE `username` = :username");
$stmt->execute(array(':username' => $username));
$TLSData = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
return $TLSData;
}
function remaining_specs($domain, $object = null, $js = null) {
// left_m without object given = MiB left in domain
// left_m with object given = Max. MiB we can assign to given object
// limit_m = Domain limit in MiB
// left_c = Mailboxes we can create depending on domain quota
global $pdo;
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
return false;
}
try {
$stmt = $pdo->prepare("SELECT `mailboxes`, `maxquota`, `quota` FROM `domain` WHERE `domain` = :domain");
$stmt->execute(array(':domain' => $domain));
$DomainData = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt = $pdo->prepare("SELECT COUNT(*) AS `count`, COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `in_use_m` FROM `mailbox` WHERE `domain` = :domain AND `username` != :object");
$stmt->execute(array(':domain' => $domain, ':object' => $object));
$MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
$quota_left_m = $DomainData['quota'] - $MailboxDataDomain['in_use_m'];
$mboxs_left = $DomainData['mailboxes'] - $MailboxDataDomain['count'];
if ($quota_left_m > $DomainData['maxquota']) {
$quota_left_m = $DomainData['maxquota'];
}
}
catch (PDOException $e) {
return false;
}
if (is_numeric($quota_left_m)) {
$spec['left_m'] = $quota_left_m;
$spec['limit_m'] = $DomainData['maxquota'];
}
if (is_numeric($mboxs_left)) {
$spec['left_c'] = $mboxs_left;
}
if (!empty($js)) {
echo $quota_left_m;
exit;
}
return $spec;
}
function get_sender_acl_handles($mailbox, $which) {
global $pdo;
if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
return false;
}
switch ($which) {
case "preselected":
try {
$stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` = :goto AND `address` NOT LIKE '@%'");
$stmt->execute(array(':goto' => $mailbox));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $rows;
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
break;
case "selected":
try {
$stmt = $pdo->prepare("SELECT `send_as` FROM `sender_acl` WHERE `logged_in_as` = :logged_in_as");
$stmt->execute(array(':logged_in_as' => $mailbox));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $rows;
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
break;
case "unselected-domains":
try {
if ($_SESSION['mailcow_cc_role'] == "admin" ) {
$stmt = $pdo->prepare("SELECT DISTINCT `domain` FROM `domain`
WHERE `domain` NOT IN (
SELECT REPLACE(`send_as`, '@', '') FROM `sender_acl`
WHERE `logged_in_as` = :logged_in_as)
AND `domain` NOT IN (
SELECT REPLACE(`address`, '@', '') FROM `alias`
WHERE `goto` = :goto)");
$stmt->execute(array(
':logged_in_as' => $mailbox,
':goto' => $mailbox,
));
}
else {
$stmt = $pdo->prepare("SELECT DISTINCT `domain` FROM `domain_admins`
WHERE `username` = :username
AND `domain` != 'ALL'
AND `domain` NOT IN (
SELECT REPLACE(`send_as`, '@', '') FROM `sender_acl`
WHERE `logged_in_as` = :logged_in_as)");
$stmt->execute(array(
':logged_in_as' => $mailbox,
':username' => $_SESSION['mailcow_cc_username']
));
}
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $rows;
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
break;
case "unselected-addresses":
try {
if ($_SESSION['mailcow_cc_role'] == "admin" ) {
$stmt = $pdo->prepare("SELECT `address` FROM `alias`
WHERE `goto` != :goto
AND `address` NOT IN (
SELECT `send_as` FROM `sender_acl`
WHERE `logged_in_as` = :logged_in_as)");
$stmt->execute(array(
':logged_in_as' => $mailbox,
':goto' => $mailbox
));
}
else {
$stmt = $pdo->prepare("SELECT `address` FROM `alias`
WHERE `goto` != :goto
AND `domain` IN (
SELECT `domain` FROM `domain_admins`
WHERE `username` = :username)
AND `address` NOT IN (
SELECT `send_as` FROM `sender_acl`
WHERE `logged_in_as` = :logged_in_as)");
$stmt->execute(array(
':logged_in_as' => $mailbox,
':goto' => $mailbox,
':username' => $_SESSION['mailcow_cc_username']
));
}
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $rows;
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
break;
}
return false;
}
function tagging_options($action, $data = null) {
global $lang;
global $pdo;
$username = $_SESSION['mailcow_cc_username'];
if ($action == "get") {
if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
return false;
}
try {
$stmt = $pdo->prepare("SELECT `wants_tagged_subject` FROM `mailbox` WHERE `username` = :username");
$stmt->execute(array(':username' => $username));
$SelectData = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
return $SelectData['wants_tagged_subject'];
}
elseif ($action == "set") {
($data['tagged_mail_handler'] == "subject") ? $wants_tagged_subject = '1' : $wants_tagged_subject = '0';
if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['username_invalid'])
);
return false;
}
try {
$stmt = $pdo->prepare("UPDATE `mailbox` SET `wants_tagged_subject` = :wants_tagged_subject WHERE `username` = :username");
$stmt->execute(array(':username' => $username, ':wants_tagged_subject' => $wants_tagged_subject));
$SelectData = $stmt->fetch(PDO::FETCH_ASSOC);
}
catch(PDOException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'MySQL: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => sprintf($lang['success']['mailbox_modified'], $username)
);
}
return false;
}
-function user_object_info($action, $data = null) {
+function user_get_alias_details($username) {
global $lang;
global $pdo;
- $username = $_SESSION['mailcow_cc_username'];
- if ($action == "get") {
- if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
- return false;
+ if ($_SESSION['mailcow_cc_role'] == "user") {
+ $username = $_SESSION['mailcow_cc_username'];
+ }
+ if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
+ return false;
+ }
+ try {
+ $data['address'] = $username;
+ $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '&#10008;') AS `aliases` FROM `alias` WHERE `goto` = :username_goto AND `address` NOT LIKE '@%' AND `address` != :username_address");
+ $stmt->execute(array(':username_goto' => $username, ':username_address' => $username));
+ $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($run)) {
+ $data['aliases'] = $row['aliases'];
}
- try {
- $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '&#10008;') AS `aliases` FROM `alias` WHERE `goto` = :username_goto AND `address` NOT LIKE '@%' AND `address` != :username_address");
- $stmt->execute(array(':username_goto' => $username, ':username_address' => $username));
- $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($run)) {
- $data['aliases'] = $row['aliases'];
- }
- $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`send_as` SEPARATOR ', '), '&#10008;') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :username AND `send_as` NOT LIKE '@%';");
- $stmt->execute(array(':username' => $username));
- $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($run)) {
- $data['aliases_also_send_as'] = $row['send_as'];
- }
- $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`send_as` SEPARATOR ', '), '&#10008;') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :username AND `send_as` LIKE '@%';");
- $stmt->execute(array(':username' => $username));
- $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($run)) {
- $data['aliases_send_as_all'] = $row['send_as'];
- }
- $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '&#10008;') as `address` FROM `alias` WHERE `goto` = :username AND `address` LIKE '@%';");
- $stmt->execute(array(':username' => $username));
- $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($run)) {
- $data['is_catch_all'] = $row['address'];
- }
- return $data;
+ $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(local_part, '@', alias_domain SEPARATOR ', '), '&#10008;') AS `ad_alias` FROM `mailbox`
+ LEFT OUTER JOIN `alias_domain` on `target_domain` = `domain`
+ WHERE `username` = :username ;");
+ $stmt->execute(array(':username' => $username));
+ $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($run)) {
+ $data['ad_alias'] = $row['ad_alias'];
}
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
+ $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`send_as` SEPARATOR ', '), '&#10008;') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :username AND `send_as` NOT LIKE '@%';");
+ $stmt->execute(array(':username' => $username));
+ $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($run)) {
+ $data['aliases_also_send_as'] = $row['send_as'];
+ }
+ $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`send_as` SEPARATOR ', '), '&#10008;') AS `send_as` FROM `sender_acl` WHERE `logged_in_as` = :username AND `send_as` LIKE '@%';");
+ $stmt->execute(array(':username' => $username));
+ $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($run)) {
+ $data['aliases_send_as_all'] = $row['send_as'];
+ }
+ $stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '&#10008;') as `address` FROM `alias` WHERE `goto` = :username AND `address` LIKE '@%';");
+ $stmt->execute(array(':username' => $username));
+ $run = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($run)) {
+ $data['is_catch_all'] = $row['address'];
}
+ return $data;
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
}
- return false;
}
function is_valid_domain_name($domain_name) {
if (empty($domain_name)) {
return false;
}
$domain_name = idn_to_ascii($domain_name);
return (preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name)
&& preg_match("/^.{1,253}$/", $domain_name)
&& preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name));
}
?>
diff --git a/data/web/inc/header.inc.php b/data/web/inc/header.inc.php
index d72ec73f..43e1119c 100644
--- a/data/web/inc/header.inc.php
+++ b/data/web/inc/header.inc.php
@@ -1,245 +1,249 @@
<!DOCTYPE html>
<html lang="<?= $_SESSION['mailcow_locale'] ?>">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>mailcow UI</title>
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js" integrity="sha384-XxcvoeNF5V0ZfksTnV+bejnCsJjOOIzN6UVwF85WBsAnU3zeYh5bloN+L4WLgeNE" crossorigin="anonymous"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.6/<?=strtolower(trim($DEFAULT_THEME));?>/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.9.4/css/bootstrap-select.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/7.0.2/css/bootstrap-slider.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.2/css/bootstrap3/bootstrap-switch.min.css">
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Source+Sans+Pro:400,600,700&subset=latin,latin-ext">
<link rel="stylesheet" href="/inc/languages.min.css">
<link rel="shortcut icon" href="/favicon.png" type="image/png">
<link rel="icon" href="/favicon.png" type="image/png">
<style>
#maxmsgsize { min-width: 80px; }
ul[id*="sortable"] { word-wrap: break-word; list-style-type: none; float: left; padding: 0 15px 0 0; width: 48%; cursor:move}
ul[id$="sortable-active"] li {cursor:move; }
ul[id$="sortable-inactive"] li {cursor:move }
.list-heading { cursor:default !important}
.ui-state-disabled { cursor:no-drop; color:#ccc; }
.ui-state-highlight {background: #F5F5F5 !important; height: 41px !important; cursor:move }
#slider1 .slider-selection {
background: #FFD700;
}
#slider1 .slider-track-high {
background: #FF4500;
}
#slider1 .slider-track-low {
background: #66CD00;
}
table[data-sortable] {
border-collapse: collapse;
border-spacing: 0;
}
table[data-sortable] th {
vertical-align: bottom;
font-weight: bold;
}
table[data-sortable] th, table[data-sortable] td {
text-align: left;
padding: 10px;
}
table[data-sortable] th:not([data-sortable="false"]) {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-touch-callout: none;
cursor: pointer;
}
table[data-sortable] th:after {
content: "";
visibility: hidden;
display: inline-block;
vertical-align: inherit;
height: 0;
width: 0;
border-width: 5px;
border-style: solid;
border-color: transparent;
margin-right: 1px;
margin-left: 10px;
float: right;
}
table[data-sortable] th[data-sortable="false"]:after {
display: none;
}
table[data-sortable] th[data-sorted="true"]:after {
visibility: visible;
}
table[data-sortable] th[data-sorted-direction="descending"]:after {
border-top-color: inherit;
margin-top: 8px;
}
table[data-sortable] th[data-sorted-direction="ascending"]:after {
border-bottom-color: inherit;
margin-top: 3px;
}
table[data-sortable].sortable-theme-bootstrap thead th {
border-bottom: 2px solid #e0e0e0;
}
table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"] {
color: #3a87ad;
background: #d9edf7;
border-bottom-color: #bce8f1;
}
table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"][data-sorted-direction="descending"]:after {
border-top-color: #3a87ad;
}
table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"][data-sorted-direction="ascending"]:after {
border-bottom-color: #3a87ad;
}
table[data-sortable].sortable-theme-bootstrap.sortable-theme-bootstrap-striped tbody > tr:nth-child(odd) > td {
background-color: #f9f9f9;
}
.btn {
text-transform: none;
}
#data td, #no-data td {
vertical-align: middle;
}
.sort-table:hover {
border-bottom-color: #00B7DC !important;
}
.striped:nth-child(odd) {
background-color: #fff;
}
.striped:nth-child(even) {
background-color: #fafafa;
border:1px solid white;
}
.glyphicon-spin {
-webkit-animation: spin 1000ms infinite linear;
animation: spin 1000ms infinite linear;
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
</style>
<?php
if (preg_match("/mailbox.php/i", $_SERVER['REQUEST_URI'])):
?>
<style>
.panel-heading div {
margin-top: -18px;
font-size: 15px;
}
.panel-heading div span {
margin-left:5px;
}
.panel-body {
display: none;
}
.clickable {
cursor: pointer;
}
.progress {
margin-bottom: 0px;
}
</style>
<?php
endif;
?>
</head>
<body style="padding-top:70px">
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/"><img height="32" alt="mailcow-logo" style="margin-top:-5px;" src="/img/cow_mailcow.svg" /></a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<?php
if (isset($_SESSION['mailcow_locale'])) {
?>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><span class="lang-sm lang-lbl" lang="<?=$_SESSION['mailcow_locale'];?>"></span><span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li <?=($_SESSION['mailcow_locale'] == 'de') ? 'class="active"' : ''?>> <a href="?<?= http_build_query(array_merge($_GET, array("lang" => "de"))) ?>"><span class="lang-xs lang-lbl-full" lang="de"></span></a></li>
<li <?=($_SESSION['mailcow_locale'] == 'en') ? 'class="active"' : ''?>> <a href="?<?= http_build_query(array_merge($_GET, array("lang" => "en"))) ?>"><span class="lang-xs lang-lbl-full" lang="en"></span></a></li>
<li <?=($_SESSION['mailcow_locale'] == 'nl') ? 'class="active"' : ''?>> <a href="?<?= http_build_query(array_merge($_GET, array("lang" => "nl"))) ?>"><span class="lang-xs lang-lbl-full" lang="nl"></span></a></li>
<li <?=($_SESSION['mailcow_locale'] == 'pt') ? 'class="active"' : ''?>> <a href="?<?= http_build_query(array_merge($_GET, array("lang" => "pt"))) ?>"><span class="lang-xs lang-lbl-full" lang="pt"></span></a></li>
</ul>
</li>
<?php
}
if (isset($_SESSION['mailcow_cc_role'])) {
?>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><?=$lang['header']['mailcow_settings'];?><span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<?php
if (isset($_SESSION['mailcow_cc_role'])) {
if ($_SESSION['mailcow_cc_role'] == "admin") {
?>
<li <?=(preg_match("/admin/i", $_SERVER['REQUEST_URI'])) ? 'class="active"' : ''?>><a href="/admin.php"><?=$lang['header']['administration'];?></a></li>
<?php
}
if ($_SESSION['mailcow_cc_role'] == "admin" || $_SESSION['mailcow_cc_role'] == "domainadmin") {
?>
<li <?=(preg_match("/mailbox/i", $_SERVER['REQUEST_URI'])) ? 'class="active"' : ''?>><a href="/mailbox.php"><?=$lang['header']['mailboxes'];?></a></li>
<?php
}
if ($_SESSION['mailcow_cc_role'] == "user") {
?>
<li <?=(preg_match("/user/i", $_SERVER['REQUEST_URI'])) ? 'class="active"' : ''?>><a href="/user.php"><?=$lang['header']['user_settings'];?></a></li>
<?php
}
}
?>
</ul>
</li>
<?php
if ($_SESSION['mailcow_cc_role'] == "admin"):
?>
<li><a href data-toggle="modal" data-target="#RestartSOGo"><span style="font-size:12px" class="glyphicon glyphicon-refresh" aria-hidden="true"></span> <?=$lang['header']['restart_sogo'];?></a></li>
<?php
endif;
?>
<?php
}
- if (isset($_SESSION['mailcow_cc_username'])):
+ if (!isset($_SESSION["dual-login"]) && isset($_SESSION['mailcow_cc_username'])):
?>
<li><a style="border-left:1px solid #E7E7E7" href="#" onclick="logout.submit()"><?=sprintf($lang['header']['logged_in_as_logout'], $_SESSION['mailcow_cc_username']);?></a></li>
<?php
+ elseif (isset($_SESSION["dual-login"])):
+ ?>
+ <li><a style="border-left:1px solid #E7E7E7" href="#" onclick="logout.submit()"><?=sprintf($lang['header']['logged_in_as_logout_dual'], $_SESSION['mailcow_cc_username'], $_SESSION["dual-login"]["username"]);?></a></li>
+ <?php
endif;
?>
</ul>
</div><!--/.nav-collapse -->
</div><!--/.container-fluid -->
</nav>
<form action="/" method="post" id="logout"><input type="hidden" name="logout"></form>
diff --git a/data/web/inc/init.sql b/data/web/inc/init.sql
index a85d6bfb..64d7da5a 100644
--- a/data/web/inc/init.sql
+++ b/data/web/inc/init.sql
@@ -1,263 +1,268 @@
CREATE TABLE IF NOT EXISTS `admin` (
- `username` varchar(255) NOT NULL,
- `password` varchar(255) NOT NULL,
- `superadmin` tinyint(1) NOT NULL DEFAULT '0',
- `created` datetime NOT NULL DEFAULT '2016-01-01 00:00:00',
- `modified` datetime NOT NULL DEFAULT '2016-01-01 00:00:00',
- `active` tinyint(1) NOT NULL DEFAULT '1',
+ `username` VARCHAR(255) NOT NULL,
+ `password` VARCHAR(255) NOT NULL,
+ `superadmin` TINYINT(1) NOT NULL DEFAULT '0',
+ `created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
+ `modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
+ `active` TINYINT(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS `alias` (
- `address` varchar(255) NOT NULL,
- `goto` text NOT NULL,
- `domain` varchar(255) NOT NULL,
- `created` datetime NOT NULL DEFAULT '2016-01-01 00:00:00',
- `modified` datetime NOT NULL DEFAULT '2016-01-01 00:00:00',
- `active` tinyint(1) NOT NULL DEFAULT '1',
+ `address` VARCHAR(255) NOT NULL,
+ `goto` TEXT NOT NULL,
+ `domain` VARCHAR(255) NOT NULL,
+ `created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
+ `modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
+ `active` TINYINT(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`address`),
KEY `domain` (`domain`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS `sender_acl` (
- `logged_in_as` varchar(255) NOT NULL,
- `send_as` varchar(255) NOT NULL
+ `logged_in_as` VARCHAR(255) NOT NULL,
+ `send_as` VARCHAR(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS `spamalias` (
- `address` varchar(255) NOT NULL,
- `goto` text NOT NULL,
- `validity` int(11) NOT NULL,
+ `address` VARCHAR(255) NOT NULL,
+ `goto` TEXT NOT NULL,
+ `validity` INT(11) NOT NULL,
PRIMARY KEY (`address`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS `alias_domain` (
- `alias_domain` varchar(255) NOT NULL,
- `target_domain` varchar(255) NOT NULL,
- `created` datetime NOT NULL DEFAULT '2016-01-01 00:00:00',
- `modified` datetime NOT NULL DEFAULT '2016-01-01 00:00:00',
- `active` tinyint(1) NOT NULL DEFAULT '1',
+ `alias_domain` VARCHAR(255) NOT NULL,
+ `target_domain` VARCHAR(255) NOT NULL,
+ `created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
+ `modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
+ `active` TINYINT(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`alias_domain`),
KEY `active` (`active`),
KEY `target_domain` (`target_domain`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS `domain` (
- `domain` varchar(255) NOT NULL,
- `description` varchar(255),
- `aliases` int(10) NOT NULL DEFAULT '0',
- `mailboxes` int(10) NOT NULL DEFAULT '0',
- `maxquota` bigint(20) NOT NULL DEFAULT '0',
- `quota` bigint(20) NOT NULL DEFAULT '0',
- `transport` varchar(255) NOT NULL,
- `backupmx` tinyint(1) NOT NULL DEFAULT '0',
- `relay_all_recipients` tinyint(1) NOT NULL DEFAULT '0',
- `created` datetime NOT NULL DEFAULT '2016-01-01 00:00:00',
- `modified` datetime NOT NULL DEFAULT '2016-01-01 00:00:00',
- `active` tinyint(1) NOT NULL DEFAULT '1',
+ `domain` VARCHAR(255) NOT NULL,
+ `description` VARCHAR(255),
+ `aliases` INT(10) NOT NULL DEFAULT '0',
+ `mailboxes` INT(10) NOT NULL DEFAULT '0',
+ `maxquota` BIGINT(20) NOT NULL DEFAULT '0',
+ `quota` BIGINT(20) NOT NULL DEFAULT '0',
+ `transport` VARCHAR(255) NOT NULL,
+ `backupmx` TINYINT(1) NOT NULL DEFAULT '0',
+ `relay_all_recipients` TINYINT(1) NOT NULL DEFAULT '0',
+ `created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
+ `modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
+ `active` TINYINT(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`domain`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS `domain_admins` (
- `username` varchar(255) NOT NULL,
- `domain` varchar(255) NOT NULL,
- `created` datetime NOT NULL DEFAULT '2016-01-01 00:00:00',
- `active` tinyint(1) NOT NULL DEFAULT '1',
+ `username` VARCHAR(255) NOT NULL,
+ `domain` VARCHAR(255) NOT NULL,
+ `created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
+ `active` TINYINT(1) NOT NULL DEFAULT '1',
KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS `mailbox` (
- `username` varchar(255) NOT NULL,
- `password` varchar(255) NOT NULL,
- `name` varchar(255),
- `maildir` varchar(255) NOT NULL,
- `quota` bigint(20) NOT NULL DEFAULT '0',
- `local_part` varchar(255) NOT NULL,
- `domain` varchar(255) NOT NULL,
- `created` datetime NOT NULL DEFAULT '2016-01-01 00:00:00',
- `modified` datetime NOT NULL DEFAULT '2016-01-01 00:00:00',
- `tls_enforce_in` tinyint(1) NOT NULL DEFAULT '0',
- `tls_enforce_out` tinyint(1) NOT NULL DEFAULT '0',
- `kind` varchar(100) NOT NULL DEFAULT '',
- `multiple_bookings` tinyint(1) NOT NULL DEFAULT '0',
- `wants_tagged_subject` tinyint(1) NOT NULL DEFAULT '0',
- `active` tinyint(1) NOT NULL DEFAULT '1',
+ `username` VARCHAR(255) NOT NULL,
+ `password` VARCHAR(255) NOT NULL,
+ `name` VARCHAR(255),
+ `maildir` VARCHAR(255) NOT NULL,
+ `quota` BIGINT(20) NOT NULL DEFAULT '0',
+ `local_part` VARCHAR(255) NOT NULL,
+ `domain` VARCHAR(255) NOT NULL,
+ `created` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
+ `modified` DATETIME NOT NULL DEFAULT '2016-01-01 00:00:00',
+ `tls_enforce_in` TINYINT(1) NOT NULL DEFAULT '0',
+ `tls_enforce_out` TINYINT(1) NOT NULL DEFAULT '0',
+ `kind` VARCHAR(100) NOT NULL DEFAULT '',
+ `multiple_bookings` TINYINT(1) NOT NULL DEFAULT '0',
+ `wants_tagged_subject` TINYINT(1) NOT NULL DEFAULT '0',
+ `active` TINYINT(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`username`),
KEY `domain` (`domain`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS `quota2` (
- `username` varchar(100) NOT NULL,
- `bytes` bigint(20) NOT NULL DEFAULT '0',
- `messages` int(11) NOT NULL DEFAULT '0',
+ `username` VARCHAR(100) NOT NULL,
+ `bytes` BIGINT(20) NOT NULL DEFAULT '0',
+ `messages` INT(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS `filterconf` (
- `object` varchar(100) NOT NULL DEFAULT '',
- `option` varchar(50) NOT NULL DEFAULT '',
- `value` varchar(100) NOT NULL DEFAULT '',
- `prefid` int(11) NOT NULL AUTO_INCREMENT,
+ `object` VARCHAR(100) NOT NULL DEFAULT '',
+ `option` VARCHAR(50) NOT NULL DEFAULT '',
+ `value` VARCHAR(100) NOT NULL DEFAULT '',
+ `prefid` INT(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`prefid`),
KEY `object` (`object`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS `imapsync` (
- `id` int NOT NULL AUTO_INCREMENT,
- `user2` varchar(255) NOT NULL,
- `host1` varchar(255) NOT NULL,
+ `id` INT NOT NULL AUTO_INCREMENT,
+ `user2` VARCHAR(255) NOT NULL,
+ `host1` VARCHAR(255) NOT NULL,
`authmech1` ENUM('PLAIN','LOGIN','CRAM-MD5') DEFAULT 'PLAIN',
- `user1` varchar(255) NOT NULL,
- `password1` varchar(255) NOT NULL,
+ `regextrans2` VARCHAR(255) DEFAULT '',
+ `authmd51` TINYINT(1) NOT NULL DEFAULT 0,
+ `domain2` VARCHAR(255) NOT NULL DEFAULT '',
+ `subfolder2` VARCHAR(255) NOT NULL DEFAULT '',
+ `user1` VARCHAR(255) NOT NULL,
+ `password1` VARCHAR(255) NOT NULL,
`exclude` VARCHAR(500) NOT NULL DEFAULT '',
- `mins_interval` VARCHAR(50) NOT NULL,
+ `maxage` SMALLINT NOT NULL DEFAULT '0',
+ `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,
`active` TINYINT(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
DROP VIEW IF EXISTS grouped_mail_aliases;
DROP VIEW IF EXISTS grouped_sender_acl;
DROP VIEW IF EXISTS grouped_domain_alias_address;
CREATE VIEW grouped_mail_aliases (username, aliases) AS
SELECT goto, IFNULL(GROUP_CONCAT(address SEPARATOR ' '), '') AS address FROM alias
WHERE address!=goto
AND active = '1'
AND address NOT LIKE '@%'
GROUP BY goto;
CREATE VIEW grouped_sender_acl (username, send_as) AS
SELECT logged_in_as, IFNULL(GROUP_CONCAT(send_as SEPARATOR ' '), '') AS send_as FROM sender_acl
WHERE send_as NOT LIKE '@%'
GROUP BY logged_in_as;
CREATE VIEW grouped_domain_alias_address (username, ad_alias) AS
SELECT username, IFNULL(GROUP_CONCAT(local_part, '@', alias_domain SEPARATOR ' '), '') AS ad_alias FROM mailbox
LEFT OUTER JOIN alias_domain on target_domain=domain GROUP BY username;
CREATE TABLE IF NOT EXISTS sogo_acl (
- c_folder_id integer NOT NULL,
+ c_folder_id INTeger NOT NULL,
c_object character varying(255) NOT NULL,
c_uid character varying(255) NOT NULL,
c_role character varying(80) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS sogo_alarms_folder (
- c_path varchar(255) NOT NULL,
- c_name varchar(255) NOT NULL,
- c_uid varchar(255) NOT NULL,
- c_recurrence_id int(11) DEFAULT NULL,
- c_alarm_number int(11) NOT NULL,
- c_alarm_date int(11) NOT NULL
+ c_path VARCHAR(255) NOT NULL,
+ c_name VARCHAR(255) NOT NULL,
+ c_uid VARCHAR(255) NOT NULL,
+ c_recurrence_id INT(11) DEFAULT NULL,
+ c_alarm_number INT(11) NOT NULL,
+ c_alarm_date INT(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS sogo_cache_folder (
- c_uid varchar(255) NOT NULL,
- c_path varchar(255) NOT NULL,
- c_parent_path varchar(255) DEFAULT NULL,
- c_type tinyint(3) unsigned NOT NULL,
- c_creationdate int(11) NOT NULL,
- c_lastmodified int(11) NOT NULL,
- c_version int(11) NOT NULL DEFAULT '0',
- c_deleted tinyint(4) NOT NULL DEFAULT '0',
- c_content longtext,
+ c_uid VARCHAR(255) NOT NULL,
+ c_path VARCHAR(255) NOT NULL,
+ c_parent_path VARCHAR(255) DEFAULT NULL,
+ c_type TINYINT(3) unsigned NOT NULL,
+ c_creationdate INT(11) NOT NULL,
+ c_lastmodified INT(11) NOT NULL,
+ c_version INT(11) NOT NULL DEFAULT '0',
+ c_deleted TINYINT(4) NOT NULL DEFAULT '0',
+ c_content longTEXT,
PRIMARY KEY (c_uid,c_path)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS sogo_folder_info (
- c_folder_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
- c_path varchar(255) NOT NULL,
- c_path1 varchar(255) NOT NULL,
- c_path2 varchar(255) DEFAULT NULL,
- c_path3 varchar(255) DEFAULT NULL,
- c_path4 varchar(255) DEFAULT NULL,
- c_foldername varchar(255) NOT NULL,
- c_location integer NULL,
- c_quick_location varchar(2048) DEFAULT NULL,
- c_acl_location varchar(2048) DEFAULT NULL,
- c_folder_type varchar(255) NOT NULL,
+ c_folder_id BIGINT(20) unsigned NOT NULL AUTO_INCREMENT,
+ c_path VARCHAR(255) NOT NULL,
+ c_path1 VARCHAR(255) NOT NULL,
+ c_path2 VARCHAR(255) DEFAULT NULL,
+ c_path3 VARCHAR(255) DEFAULT NULL,
+ c_path4 VARCHAR(255) DEFAULT NULL,
+ c_foldername VARCHAR(255) NOT NULL,
+ c_location INTeger NULL,
+ c_quick_location VARCHAR(2048) DEFAULT NULL,
+ c_acl_location VARCHAR(2048) DEFAULT NULL,
+ c_folder_type VARCHAR(255) NOT NULL,
PRIMARY KEY (c_path),
UNIQUE KEY c_folder_id (c_folder_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
-CREATE TABLE IF NOT EXISTS sogo_quick_appointment (
- c_folder_id integer NOT NULL,
+CREATE TABLE IF NOT EXISTS sogo_quick_appoINTment (
+ c_folder_id INTeger NOT NULL,
c_name character varying(255) NOT NULL,
c_uid character varying(255) NOT NULL,
- c_startdate integer,
- c_enddate integer,
- c_cycleenddate integer,
+ c_startdate INTeger,
+ c_enddate INTeger,
+ c_cycleenddate INTeger,
c_title character varying(1000) NOT NULL,
- c_participants text,
- c_isallday integer,
- c_iscycle integer,
- c_cycleinfo text,
- c_classification integer NOT NULL,
- c_isopaque integer NOT NULL,
- c_status integer NOT NULL,
- c_priority integer,
+ c_participants TEXT,
+ c_isallday INTeger,
+ c_iscycle INTeger,
+ c_cycleinfo TEXT,
+ c_classification INTeger NOT NULL,
+ c_isopaque INTeger NOT NULL,
+ c_status INTeger NOT NULL,
+ c_priority INTeger,
c_location character varying(255),
c_orgmail character varying(255),
- c_partmails text,
- c_partstates text,
+ c_partmails TEXT,
+ c_partstates TEXT,
c_category character varying(255),
- c_sequence integer,
+ c_sequence INTeger,
c_component character varying(10) NOT NULL,
- c_nextalarm integer,
- c_description text,
- CONSTRAINT sogo_quick_appointment_pkey PRIMARY KEY (c_folder_id, c_name)
+ c_nextalarm INTeger,
+ c_description TEXT,
+ CONSTRAINT sogo_quick_appoINTment_pkey PRIMARY KEY (c_folder_id, c_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS sogo_quick_contact (
- c_folder_id integer NOT NULL,
+ c_folder_id INTeger NOT NULL,
c_name character varying(255) NOT NULL,
c_givenname character varying(255),
c_cn character varying(255),
c_sn character varying(255),
c_screenname character varying(255),
c_l character varying(255),
c_mail character varying(255),
c_o character varying(255),
c_ou character varying(255),
c_telephonenumber character varying(255),
c_categories character varying(255),
c_component character varying(10) NOT NULL,
CONSTRAINT sogo_quick_contact_pkey PRIMARY KEY (c_folder_id, c_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS sogo_sessions_folder (
- c_id varchar(255) NOT NULL,
- c_value varchar(255) NOT NULL,
- c_creationdate int(11) NOT NULL,
- c_lastseen int(11) NOT NULL,
+ c_id VARCHAR(255) NOT NULL,
+ c_value VARCHAR(255) NOT NULL,
+ c_creationdate INT(11) NOT NULL,
+ c_lastseen INT(11) NOT NULL,
PRIMARY KEY (c_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS sogo_store (
- c_folder_id integer NOT NULL,
+ c_folder_id INTeger NOT NULL,
c_name character varying(255) NOT NULL,
- c_content mediumtext NOT NULL,
- c_creationdate integer NOT NULL,
- c_lastmodified integer NOT NULL,
- c_version integer NOT NULL,
- c_deleted integer,
+ c_content mediumTEXT NOT NULL,
+ c_creationdate INTeger NOT NULL,
+ c_lastmodified INTeger NOT NULL,
+ c_version INTeger NOT NULL,
+ c_deleted INTeger,
CONSTRAINT sogo_store_pkey PRIMARY KEY (c_folder_id, c_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS sogo_user_profile (
- c_uid varchar(255) NOT NULL,
- c_defaults text,
- c_settings text,
+ c_uid VARCHAR(255) NOT NULL,
+ c_defaults TEXT,
+ c_settings TEXT,
PRIMARY KEY (c_uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
REPLACE INTO admin (username, password, superadmin, created, modified, active) VALUES ('admin', '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1);
DELETE FROM domain_admins WHERE domain='all';
INSERT INTO domain_admins (username, domain, created, active) VALUES ('admin', 'ALL', NOW(), 1);
diff --git a/data/web/inc/prerequisites.inc.php b/data/web/inc/prerequisites.inc.php
index cec7454d..4ec73e52 100644
--- a/data/web/inc/prerequisites.inc.php
+++ b/data/web/inc/prerequisites.inc.php
@@ -1,78 +1,85 @@
<?php
//ini_set("session.cookie_secure", 1);
//ini_set("session.cookie_httponly", 1);
session_start();
if (isset($_POST["logout"])) {
- session_unset();
- session_destroy();
- session_write_close();
- setcookie(session_name(),'',0,'/');
+ if (isset($_SESSION["dual-login"])) {
+ $_SESSION["mailcow_cc_username"] = $_SESSION["dual-login"]["username"];
+ $_SESSION["mailcow_cc_role"] = $_SESSION["dual-login"]["role"];
+ unset($_SESSION["dual-login"]);
+ }
+ else {
+ session_unset();
+ session_destroy();
+ session_write_close();
+ setcookie(session_name(),'',0,'/');
+ }
}
require_once 'inc/vars.inc.php';
if (file_exists('./inc/vars.local.inc.php')) {
include_once 'inc/vars.local.inc.php';
}
$dsn = "$database_type:host=$database_host;dbname=$database_name";
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
}
catch (PDOException $e) {
?>
<center style='font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;'>🐮 Connection failed, database may be in warm-up state, please try again later.<br /><br />The following error was reported:<br/> <?=$e->getMessage();?></center>
<?php
}
$_SESSION['mailcow_locale'] = strtolower(trim($DEFAULT_LANG));
setcookie('language', $DEFAULT_LANG);
if (isset($_COOKIE['language'])) {
switch ($_COOKIE['language']) {
case "de":
$_SESSION['mailcow_locale'] = 'de';
setcookie('language', 'de');
break;
case "en":
$_SESSION['mailcow_locale'] = 'en';
setcookie('language', 'en');
break;
case "nl":
$_SESSION['mailcow_locale'] = 'nl';
setcookie('language', 'nl');
break;
case "pt":
$_SESSION['mailcow_locale'] = 'pt';
setcookie('language', 'pt');
break;
}
}
if (isset($_GET['lang'])) {
switch ($_GET['lang']) {
case "de":
$_SESSION['mailcow_locale'] = 'de';
setcookie('language', 'de');
break;
case "en":
$_SESSION['mailcow_locale'] = 'en';
setcookie('language', 'en');
break;
case "nl":
$_SESSION['mailcow_locale'] = 'nl';
setcookie('language', 'nl');
break;
case "pt":
$_SESSION['mailcow_locale'] = 'pt';
setcookie('language', 'pt');
break;
}
}
require_once 'lang/lang.en.php';
include 'lang/lang.'.$_SESSION['mailcow_locale'].'.php';
require_once 'inc/functions.inc.php';
require_once 'inc/triggers.inc.php';
-init_db_schema();
+(!isset($_SESSION['mailcow_cc_username'])) ? init_db_schema() : null;
diff --git a/data/web/inc/triggers.inc.php b/data/web/inc/triggers.inc.php
index c2588148..00de3a9e 100644
--- a/data/web/inc/triggers.inc.php
+++ b/data/web/inc/triggers.inc.php
@@ -1,125 +1,139 @@
<?php
if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) {
$login_user = strtolower(trim($_POST["login_user"]));
$as = check_login($login_user, $_POST["pass_user"]);
if ($as == "admin") {
$_SESSION['mailcow_cc_username'] = $login_user;
$_SESSION['mailcow_cc_role'] = "admin";
header("Location: /admin.php");
}
elseif ($as == "domainadmin") {
$_SESSION['mailcow_cc_username'] = $login_user;
$_SESSION['mailcow_cc_role'] = "domainadmin";
header("Location: /mailbox.php");
}
elseif ($as == "user") {
$_SESSION['mailcow_cc_username'] = $login_user;
$_SESSION['mailcow_cc_role'] = "user";
header("Location: /user.php");
}
else {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => $lang['danger']['login_failed']
);
}
}
if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admin") {
+ if (isset($_GET["duallogin"])) {
+ if (filter_var($_GET["duallogin"], FILTER_VALIDATE_EMAIL)) {
+ $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `username` = :duallogin");
+ $stmt->execute(array(':duallogin' => $_GET["duallogin"]));
+ $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ if ($num_results != 0) {
+ $_SESSION["dual-login"]["username"] = $_SESSION['mailcow_cc_username'];
+ $_SESSION["dual-login"]["role"] = $_SESSION['mailcow_cc_role'];
+ $_SESSION['mailcow_cc_username'] = $_GET["duallogin"];
+ $_SESSION['mailcow_cc_role'] = "user";
+ header("Location: /user.php");
+ }
+ }
+ }
if (isset($_POST["trigger_set_admin"])) {
set_admin_account($_POST);
}
if (isset($_POST["delete_dkim_record"])) {
dkim_table("delete", $_POST);
}
if (isset($_POST["add_dkim_record"])) {
dkim_table("add", $_POST);
}
if (isset($_POST["trigger_add_domain_admin"])) {
add_domain_admin($_POST);
}
if (isset($_POST["trigger_delete_domain_admin"])) {
delete_domain_admin($_POST);
}
if (isset($_POST["trigger_edit_domain_admin"])) {
edit_domain_admin($_POST);
}
}
if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "user") {
if (isset($_POST["trigger_set_user_account"])) {
set_user_account($_POST);
}
if (isset($_POST["trigger_set_spam_score"])) {
set_spam_score($_POST);
}
if (isset($_POST["trigger_set_tagging_options"])) {
tagging_options('set', $_POST);
}
if (isset($_POST["trigger_set_policy_list"])) {
set_policy_list($_POST);
}
if (isset($_POST["trigger_set_tls_policy"])) {
set_tls_policy($_POST);
}
if (isset($_POST["trigger_add_syncjob"])) {
set_syncjob($_POST, "add");
}
if (isset($_POST["trigger_edit_syncjob"])) {
set_syncjob($_POST, "edit");
}
if (isset($_POST["trigger_delete_syncjob"])) {
set_syncjob($_POST, "delete");
}
if (isset($_POST["trigger_set_time_limited_aliases"])) {
set_time_limited_aliases($_POST);
}
}
if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "admin" || $_SESSION['mailcow_cc_role'] == "domainadmin")) {
if (isset($_GET["js"])) {
switch ($_GET["js"]) {
case "remaining_specs":
remaining_specs($_GET['domain'], $_GET['object'], "y");
break;
}
}
if (isset($_POST["trigger_mailbox_action"])) {
switch ($_POST["trigger_mailbox_action"]) {
case "adddomain":
mailbox_add_domain($_POST);
break;
case "addalias":
mailbox_add_alias($_POST);
break;
case "editalias":
mailbox_edit_alias($_POST);
break;
case "addaliasdomain":
mailbox_add_alias_domain($_POST);
break;
case "addmailbox":
mailbox_add_mailbox($_POST);
break;
case "editdomain":
mailbox_edit_domain($_POST);
break;
case "editmailbox":
mailbox_edit_mailbox($_POST);
break;
case "deletedomain":
mailbox_delete_domain($_POST);
break;
case "deletealias":
mailbox_delete_alias($_POST);
break;
case "deletealiasdomain":
mailbox_delete_alias_domain($_POST);
break;
case "editaliasdomain":
mailbox_edit_alias_domain($_POST);
break;
case "deletemailbox":
mailbox_delete_mailbox($_POST);
break;
}
}
}
?>
diff --git a/data/web/js/user.js b/data/web/js/user.js
index 821ff99d..9dbca08c 100644
--- a/data/web/js/user.js
+++ b/data/web/js/user.js
@@ -1,34 +1,37 @@
$(document).ready(function() {
// Show and activate password fields after box was checked
// Hidden by default
if ( !$("#togglePwNew").is(':checked') ) {
$(".passFields").hide();
}
$('#togglePwNew').click(function() {
$("#user_new_pass").attr("disabled", !this.checked);
$("#user_new_pass2").attr("disabled", !this.checked);
var $this = $(this);
if ($this.is(':checked')) {
$(".passFields").slideDown();
} else {
$(".passFields").slideUp();
}
});
+ $(function () {
+ $('[data-toggle="tooltip"]').tooltip()
+ })
// Show generate button after time selection
$('#trigger_set_time_limited_aliases').hide();
$('#validity').change(function(){
$('#trigger_set_time_limited_aliases').show();
});
// Init Bootstrap Switch
$.fn.bootstrapSwitch.defaults.onColor = 'success';
$("[name='tls_out']").bootstrapSwitch();
$("[name='tls_in']").bootstrapSwitch();
// Log modal
$('#logModal').on('show.bs.modal', function(e) {
var logText = $(e.relatedTarget).data('log-text');
- $(e.currentTarget).find('#logText').html('<pre>' + logText + '</pre>');
+ $(e.currentTarget).find('#logText').html('<pre style="background:none;font-size:11px;line-height:1.1;border:0px">' + logText + '</pre>');
});
});
\ No newline at end of file
diff --git a/data/web/lang/lang.de.php b/data/web/lang/lang.de.php
index 328167cb..de983776 100644
--- a/data/web/lang/lang.de.php
+++ b/data/web/lang/lang.de.php
@@ -1,401 +1,408 @@
<?php
/*
//
// German language file
//
*/
$lang['footer']['loading'] = 'Einen Moment bitte...';
$lang['header']['restart_sogo'] = 'SOGo neustarten';
$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_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['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';
$lang['danger']['mailbox_quota_exceeds_domain_quota'] = 'Maximale Größe für Mailboxen überschreitet das Domain Speicherlimit';
$lang['danger']['object_is_not_numeric'] = 'Wert %s ist nicht numerisch';
$lang['success']['domain_added'] = 'Domain %s wurde angelegt';
$lang['danger']['alias_empty'] = 'Alias-Adresse darf nicht leer sein';
$lang['danger']['goto_empty'] = 'Ziel-Adresse darf nicht leer sein';
$lang['danger']['policy_list_from_exists'] = 'Ein Eintrag mit diesem Wert existiert bereits';
$lang['danger']['policy_list_from_invalid'] = 'Eintrag hat ungültiges Format';
$lang['danger']['alias_invalid'] = 'Alias-Adrese ist ungültig';
$lang['danger']['goto_invalid'] = 'Ziel-Adrese ist ungültig';
$lang['danger']['alias_domain_invalid'] = 'Alias-Domain ist ungültig';
$lang['danger']['target_domain_invalid'] = 'Ziel-Domain ist ungültig';
$lang['danger']['object_exists'] = 'Objekt %s existiert bereits';
$lang['danger']['domain_exists'] = 'Domain %s existiert bereits';
$lang['danger']['alias_goto_identical'] = 'Alias- und Ziel-Adresse dürfen nicht identisch sein';
$lang['danger']['aliasd_targetd_identical'] = 'Alias-Domain darf nicht gleich Ziel-Domain sein';
$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']['msg_size_saved'] = 'Limit wurde gesetzt';
$lang['danger']['aliasd_not_found'] = 'Alias-Domain nicht gefunden';
$lang['danger']['targetd_not_found'] = 'Ziel-Domain nicht gefunden';
$lang['danger']['aliasd_exists'] = 'Alias-Domain existiert bereits';
$lang['success']['aliasd_added'] = 'Alias-Domain %s wurde angelegt';
$lang['success']['aliasd_modified'] = 'Änderungen an Alias-Domain %s wurden gespeichert';
$lang['success']['domain_modified'] = 'Änderungen an Domain %s wurden gespeichert';
$lang['success']['domain_admin_modified'] = 'Änderungen an Domain-Administrator %s wurden gespeichert';
$lang['success']['domain_admin_added'] = 'Domain-Administrator %s wurde angelegt';
$lang['success']['changes_general'] = 'Änderungen wurden gespeichert';
$lang['success']['admin_modified'] = 'Änderungen am Administrator wurden gespeichert';
$lang['danger']['exit_code_not_null'] = 'Fehler: Exit-Code ist %d';
$lang['danger']['mailbox_not_available'] = 'Mailbox nicht verfügbar';
$lang['danger']['username_invalid'] = 'Benutzername kann nicht verwendet werden';
$lang['danger']['password_mismatch'] = 'Passwort-Wiederholung stimmt nicht überein';
$lang['danger']['password_complexity'] = 'Passwort entspricht nicht den Vorgaben';
$lang['danger']['password_empty'] = 'Passwort darf nicht leer sein';
$lang['danger']['login_failed'] = 'Anmeldung fehlgeschlagen';
$lang['danger']['mailbox_invalid'] = 'Mailboxname ist ungültig';
$lang['danger']['mailbox_invalid_suggest'] = 'Mailboxname ist ungültig, meinten Sie vielleicht "%s"?';
$lang['info']['fetchmail_planned'] = 'Aufgabe zur Mailabholung wurde geplant. Bitte prüfen Sie den Vorgangsstatus zu einem späteren Zeitpunkt noch einmal.';
$lang['danger']['fetchmail_source_empty'] = 'Bitte geben Sie einen Quell-Ordner an';
$lang['danger']['fetchmail_dest_empty'] = 'Bitte geben Sie einen Ziel-Ordner an';
$lang['danger']['is_alias'] = '%s lautet bereits eine Alias-Adresse';
$lang['danger']['is_alias_or_mailbox'] = "Eine Mailbox oder ein Alias mit der Adresse %s ist bereits vorhanden";
$lang['danger']['is_spam_alias'] = '%s lautet bereits eine Spam-Alias-Adresse';
$lang['danger']['quota_not_0_not_numeric'] = 'Speicherplatz muss numerisch und >= 0 sein';
-$lang['danger']['domain_not_found'] = 'Domain nicht gefunden.';
+$lang['danger']['domain_not_found'] = 'Domain "%s" nicht gefunden.';
$lang['danger']['max_mailbox_exceeded'] = 'Anzahl an Mailboxen überschritten (%d von %d)';
$lang['danger']['mailbox_quota_exceeded'] = 'Speicherplatz überschreitet das Limit (max. %d MiB)';
$lang['danger']['mailbox_quota_left_exceeded'] = 'Nicht genügend Speicherplatz vorhanden (Speicherplatz anwendbar: %d MiB)';
$lang['success']['mailbox_added'] = 'Mailbox %s wurde angelegt';
$lang['success']['domain_removed'] = 'Domain %s wurde entfernt';
$lang['success']['alias_removed'] = 'Alias-Adresse %s wurde entfernt';
$lang['success']['alias_domain_removed'] = 'Alias-Domain %s wurde entfernt';
$lang['success']['domain_admin_removed'] = 'Domain-Administrator %s wurde entfernt';
$lang['success']['mailbox_removed'] = 'Mailbox %s wurde entfernt';
$lang['danger']['max_quota_in_use'] = 'Mailbox Speicherplatzlimit muss größer oder gleich %d MiB sein';
$lang['danger']['domain_quota_m_in_use'] = 'Domain Speicherplatzlimit muss größer oder gleich %d MiB sein';
$lang['danger']['mailboxes_in_use'] = 'Maximale Anzahl an Mailboxen muss größer oder gleich %d sein';
$lang['danger']['aliases_in_use'] = 'Maximale Anzahl an Aliassen muss größer oder gleich %d sein';
$lang['danger']['sender_acl_invalid'] = 'Sender ACL Wert muss eine Adresse oder Domain sein';
$lang['danger']['domain_not_empty'] = 'Kann nur leere Domains entfernen';
$lang['warning']['spam_alias_temp_error'] = 'Kann zur Zeit keinen Spam-Alias erstellen, bitte versuchen Sie es später noch einmal.';
$lang['danger']['spam_alias_max_exceeded'] = 'Maximale Anzahl an Spam-Alias-Adressen erreicht';
$lang['danger']['fetchmail_active'] = 'Ein Vorgang zur Mailabholung ist bereits aktiv, bitte haben Sie etwas Geduld.';
$lang['danger']['validity_missing'] = 'Bitte geben Sie eine Gültigkeitsdauer an';
$lang['user']['on'] = 'Ein';
$lang['user']['off'] = 'Aus';
$lang['user']['user_change_fn'] = '';
$lang['user']['user_settings'] = 'Benutzereinstellungen';
$lang['user']['mailbox_settings'] = 'Mailbox-Einstellungen';
$lang['user']['mailbox_details'] = 'Mailbox-Details';
$lang['user']['change_password'] = 'Passwort ändern';
$lang['user']['new_password'] = 'Neues Passwort:';
$lang['user']['save_changes'] = 'Änderungen speichern';
$lang['user']['password_now'] = 'Aktuelles Passwort (Änderungen bestätigen):';
$lang['user']['new_password_repeat'] = 'Neues Passwort (Wiederholung):';
$lang['user']['new_password_description'] = 'Mindestanforderung: 6 Zeichen lang, Buchstaben und Zahlen.';
$lang['user']['did_you_know'] = '<b>Wussten Sie schon?</b> Sie können Ihre E-Mail-Adresse mit Tags versehen, etwa "ich+<b>Privat</b>@example.com", um Nachrichten automatisch in einem Unterordner (Beispiel: "Privat") abzulegen.';
$lang['user']['spam_aliases'] = 'Temporäre E-Mail Aliasse';
$lang['user']['alias'] = 'Alias';
$lang['user']['aliases'] = 'Aliasse';
+$lang['user']['domain_aliases'] = 'Domain-Alias Adressen';
$lang['user']['is_catch_all'] = 'Ist Catch-All Adresse für Domain(s)';
$lang['user']['aliases_also_send_as'] = 'Darf außerdem versenden als';
$lang['user']['aliases_send_as_all'] = 'Absender für folgende Domains nicht prüfen';
$lang['user']['alias_create_random'] = 'Zufälligen Alias generieren';
$lang['user']['alias_extend_all'] = 'Gültigkeit +1h';
$lang['user']['alias_valid_until'] = 'Gültig bis';
$lang['user']['alias_remove_all'] = 'Alle entfernen';
$lang['user']['alias_time_left'] = 'Zeit verbleibend';
$lang['user']['alias_full_date'] = 'd.m.Y, H:i:s T';
$lang['user']['syncjob_full_date'] = 'd.m.Y, H:i:s T';
$lang['user']['alias_select_validity'] = 'Bitte Gültigkeit auswählen';
$lang['user']['sync_jobs'] = 'Sync Jobs';
$lang['user']['hour'] = 'Stunde';
$lang['user']['hours'] = 'Stunden';
$lang['user']['day'] = 'Tag';
$lang['user']['week'] = 'Woche';
$lang['user']['weeks'] = 'Wochen';
$lang['user']['spamfilter'] = 'Spamfilter';
$lang['user']['spamfilter_wl'] = 'Whitelist';
$lang['user']['spamfilter_wl_desc'] = 'Für E-Mail-Adressen, die vom Spamfilter <b>nicht</b> erfasst werden sollen. Die Verwendung von Wildcards ist gestattet.';
$lang['user']['spamfilter_bl'] = 'Blacklist';
$lang['user']['spamfilter_bl_desc'] = 'Für E-Mail-Adressen, die vom Spamfilter <b>immer</b> als Spam erfasst und abgelehnt werden. Die Verwendung von Wildcards ist gestattet.';
$lang['user']['spamfilter_table_rule'] = 'Regel';
$lang['user']['spamfilter_table_action'] = 'Aktion';
$lang['user']['spamfilter_table_empty'] = 'Keine Einträge vorhanden';
$lang['user']['spamfilter_table_remove'] = 'entfernen';
$lang['user']['spamfilter_table_add'] = 'Eintrag hinzufügen';
$lang['user']['spamfilter_behavior'] = 'Bewertung';
$lang['user']['spamfilter_default_score'] = 'Spam-Score:';
$lang['user']['spamfilter_green'] = 'Grün: Die Nachricht ist kein Spam';
$lang['user']['spamfilter_yellow'] = 'Gelb: Die Nachricht ist vielleicht Spam, wird als Spam markiert und in den Junk-Ordner verschoben';
$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']['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';
$lang['user']['tls_enforce_in'] = 'TLS eingehend erzwingen';
$lang['user']['tls_enforce_out'] = 'TLS ausgehend erzwingen';
$lang['user']['no_record'] = 'Kein Eintrag';
$lang['user']['misc_settings'] = 'Sonstige Kontoeinstellungen';
$lang['user']['misc_delete_profile'] = 'Sonstige Kontoeinstellungen';
$lang['user']['tag_handling'] = 'Umgang mit getaggten E-Mails steuern';
$lang['user']['tag_in_subfolder'] = 'In Unterordner';
$lang['user']['tag_in_subject'] = 'In Betreff';
$lang['user']['tag_help_explain'] = 'Als Unterordner: Es wird ein Ordner mit dem Namen des Tags unterhalb der Inbox erstellt ("INBOX/Facebook").<br />
In Betreff: Der Name des Tags wird dem Betreff angefügt, etwa "[Facebook] Meine Neuigkeiten".';
$lang['user']['tag_help_example'] = 'Beispiel für eine getaggte E-Mail-Adresse: ich<b>+Facebook</b>@example.org';
$lang['user']['encryption'] = 'Verschlüsselung';
$lang['user']['username'] = 'Benutzername';
$lang['user']['password'] = 'Password';
$lang['user']['last_run'] = 'Letzte Ausführung';
$lang['user']['excludes'] = 'Ausschlüsse';
$lang['user']['interval'] = 'Intervall';
$lang['user']['active'] = 'Aktiv';
$lang['user']['action'] = 'Aktion';
$lang['user']['edit'] = 'Bearbeiten';
$lang['user']['remove'] = 'Entfernen';
+$lang['user']['delete_now'] = 'Sofort löschen';
$lang['user']['create_syncjob'] = 'Neuen Sync-Job erstellen';
$lang['start']['dashboard'] = '%s - Dashboard';
$lang['start']['start_rc'] = 'Roundcube öffnen';
$lang['start']['start_sogo'] = 'SOGo öffnen';
$lang['start']['mailcow_apps_detail'] = 'Verwenden Sie mailcow Apps, um E-Mails abzurufen, Kalender- und Kontakte zu verwalten und vieles mehr.';
$lang['start']['mailcow_panel'] = 'mailcow UI starten';
$lang['start']['mailcow_panel_description'] = 'Die mailcow Steuerung steht sowohl für Administratoren als auch Mailbox-Benutzer zur Verfügung.';
$lang['start']['mailcow_panel_detail'] = '<b>Domain-Administratoren</b> erstellen, verändern oder löschen Mailboxen, verwalten die Domäne und sehen sonstige Einstellungen ein.<br />
Als <b>Mailbox-Benutzer</b> erstellen Sie hier zeitlich limitierte Aliasse, ändern das Verhalten des Spamfilters, setzen ein neues Passwort und vieles mehr.';
$lang['start']['recommended_config'] = 'Empfohlene Software-Konfiguration (ohne ActiveSync)';
$lang['start']['imap_smtp_server'] = 'IMAP- und SMTP-Server';
$lang['start']['imap_smtp_server_description'] = 'Für eine optimale Verbindung empfehlen wir die Verwendung des <a href="%s" target="_blank"><b>Mozilla Thunderbirds</b></a>.';
$lang['start']['imap_smtp_server_badge'] = 'E-Mail lesen und schreiben';
$lang['start']['imap_smtp_server_auth_info'] = 'Bitte verwenden Sie Ihre vollständige E-Mail-Adresse sowie das PLAIN-Authentifizierungsverfahren.<br />
Ihre Anmeldedaten werden durch die obligatorische Verschlüsselung entgegen des Begriffes "PLAIN" nicht unverschlüsselt übertragen.';
$lang['start']['managesieve'] = 'ManageSieve';
$lang['start']['managesieve_badge'] = 'E-Mail-Filter';
$lang['start']['managesieve_description'] = 'Bitte verwenden Sie <b>Mozilla Thunderbirds</b> zusammen mit der <a style="text-decoration:none" target="_blank" href="%s"><b>Sieve Erweiterung</b></a>.<br />Nach dem Herunterladen der Erweiterung starten Sie Thunderbird, öffnen das Fenster für Erweiterungen und ziehen die heruntergeladene Datei in das offene Fenster.<br />Der Servername lautet <b>%s</b>, als Port konfigurieren Sie bitte <b>4190</b>. Die Anmeldedaten entsprechen dem E-Mail Login.';
$lang['start']['service'] = 'Dienstname';
$lang['start']['encryption'] = 'Verschlüsselungstyp';
$lang['start']['help'] = 'Hilfe ein-/ausblenden';
$lang['start']['hostname'] = 'Hostname';
$lang['start']['port'] = 'Port';
$lang['start']['footer'] = '';
$lang['header']['mailcow_settings'] = 'Konfiguration';
$lang['header']['administration'] = 'Administration';
$lang['header']['mailboxes'] = 'Mailboxen';
$lang['header']['user_settings'] = 'Benutzereinstellungen';
$lang['header']['login'] = 'Anmeldung';
$lang['header']['logged_in_as_logout'] = 'Eingeloggt als <b>%s</b> (abmelden)';
+$lang['header']['logged_in_as_logout_dual'] = 'Eingeloggt als <b>%s <span class="text-info">[%s]</span></b>';
$lang['header']['locale'] = 'Sprache';
$lang['mailbox']['domain'] = 'Domain';
$lang['mailbox']['alias'] = 'Alias';
$lang['mailbox']['aliases'] = 'Aliasse';
$lang['mailbox']['domains'] = 'Domains';
$lang['mailbox']['mailboxes'] = 'Mailboxen';
$lang['mailbox']['mailbox_quota'] = 'Max. Größe einer Mailbox';
$lang['mailbox']['domain_quota'] = 'Gesamtspeicher';
$lang['mailbox']['ratelimit'] = 'Limit ausgehend/Stunde';
$lang['mailbox']['active'] = 'Aktiv';
$lang['mailbox']['action'] = 'Aktion';
$lang['mailbox']['backup_mx'] = 'Backup MX';
$lang['mailbox']['domain_aliases'] = 'Domain-Aliasse';
$lang['mailbox']['target_domain'] = 'Ziel-Domain';
$lang['mailbox']['target_address'] = 'Ziel-Adresse';
$lang['mailbox']['username'] = 'Benutzername';
$lang['mailbox']['fname'] = 'Name';
$lang['mailbox']['filter_table'] = 'Tabelle filtern';
$lang['mailbox']['yes'] = '&#10004;';
$lang['mailbox']['no'] = '&#10008;';
$lang['mailbox']['quota'] = 'Speicherplatz';
$lang['mailbox']['in_use'] = 'Prozentualer Gebrauch';
$lang['mailbox']['msg_num'] = 'Anzahl Nachrichten';
$lang['mailbox']['remove'] = 'Entfernen';
$lang['mailbox']['edit'] = 'Bearbeiten';
$lang['mailbox']['archive'] = 'Archiv-Zugriff';
-$lang['mailbox']['no_record'] = 'Kein Eintrag';
+$lang['mailbox']['no_record'] = 'Kein Eintrag für Objekt %s';
$lang['mailbox']['add_domain'] = 'Domain hinzufügen';
$lang['mailbox']['add_domain_alias'] = 'Domain-Alias hinzufügen';
$lang['mailbox']['add_mailbox'] = 'Mailbox hinzufügen';
$lang['mailbox']['add_alias'] = 'Alias hinzufügen';
$lang['info']['no_action'] = 'Keine Aktion anwendbar';
$lang['delete']['title'] = 'Objekt entfernen';
$lang['delete']['remove_domain_warning'] = '<b>Warnung:</b> Sie entfernen die Domain <b>%s</b>!';
$lang['delete']['remove_domainalias_warning'] = '<b>Warnung:</b> Sie entfernen die Alias-Domain <b>%s</b>!';
$lang['delete']['remove_domainadmin_warning'] = '<b>Warnung:</b> Sie entfernen den Domain-Administrator <b>%s</b>!';
$lang['delete']['remove_alias_warning'] = '<b>Warnung:</b> Sie entfernen die Alias-Adresse <b>%s</b>!';
$lang['delete']['remove_syncjob_warning'] = '<b>Warnung:</b> Sie entfernen einen Sync-Job des Benutzers <b>%s</b>!';
$lang['delete']['remove_mailbox_warning'] = '<b>Warnung:</b> Sie entfernen die Mailbox <b>%s</b>!';
$lang['delete']['remove_mailbox_details'] = 'Die Mailbox wird <b>vollständig und permanent</b> entfernt!';
$lang['delete']['remove_domain_details'] = 'Diese Aktion entfernt ebenfalls Domain-Aliasse.<br /><br /><b>Eine Domain muss leer sein, um entfernt zu werden.</b>';
$lang['delete']['remove_syncjob_details'] = 'Objekte dieses Sync-Jobs werden nicht mehr vom entfernten Server abgeholt.';
$lang['delete']['remove_alias_details'] = 'Benutzer werden keine Nachrichten mehr von dieser Adresse erhalten und versenden koennen!</b>';
$lang['delete']['remove_button'] = 'Entfernen';
$lang['delete']['previous'] = 'Vorherige Seite';
$lang['edit']['syncjob'] = 'Sync-Job bearbeiten';
$lang['edit']['save'] = 'Änderungen speichern';
$lang['edit']['username'] = 'Benutzername';
$lang['edit']['hostname'] = 'Servername';
$lang['edit']['encryption'] = 'Verschlüsselungsmethode';
+$lang['edit']['maxage'] = 'Maximales Alter in Tagen einer Nachricht, die kopiert werden soll</br ><small>(0 = alle Nachrichten kopieren)</small>';
+$lang['edit']['subfolder2'] = 'Ziel-Ordner<br /><small>(leer = kein Unterordner)</small>';
$lang['edit']['mins_interval'] = 'Intervall (min)';
$lang['edit']['exclude'] = 'Elemente ausschließen (Regex)';
$lang['edit']['archive'] = 'Archiv-Zugriff';
$lang['edit']['max_mailboxes'] = 'Max. Mailboxanzahl:';
$lang['edit']['title'] = 'Objekt bearbeiten';
$lang['edit']['target_address'] = 'Ziel-Adresse(n) <small>(getrennt durch Komma)</small>:';
$lang['edit']['active'] = 'Aktiv';
$lang['edit']['target_domain'] = 'Ziel-Domain:';
$lang['edit']['password'] = 'Passwort:';
$lang['edit']['ratelimit'] = 'Limit ausgehender Nachrichten/Stunde:';
$lang['danger']['ratelimt_less_one'] = 'Limit ausgehender Nachrichten/Stunde darf nicht kleiner als 1 sein';
$lang['edit']['password_repeat'] = 'Passwort (Wiederholung):';
$lang['edit']['domain_admin'] = 'Domain-Administrator bearbeiten';
$lang['edit']['domain'] = 'Domain bearbeiten';
$lang['edit']['edit_alias_domain'] = 'Alias-Domain bearbeiten';
$lang['edit']['alias_domain'] = 'Alias-Domain';
$lang['edit']['domains'] = 'Domains';
$lang['edit']['destroy'] = 'Manuelle Eingabe des Wertes';
$lang['edit']['alias'] = 'Alias bearbeiten';
$lang['edit']['mailbox'] = 'Mailbox bearbeiten';
$lang['edit']['description'] = 'Beschreibung:';
$lang['edit']['max_aliases'] = 'Max. Aliasse:';
$lang['edit']['max_quota'] = 'Max. Größe per Mailbox (MiB):';
$lang['edit']['domain_quota'] = 'Domain Speicherplatz gesamt (MiB):';
$lang['edit']['backup_mx_options'] = 'Backup MX Optionen:';
$lang['edit']['relay_domain'] = 'Relay Domain';
$lang['edit']['relay_all'] = 'Alle Empfänger-Adressen relayen';
$lang['edit']['dkim_signature'] = 'DKIM-Signatur:';
$lang['edit']['dkim_record_info'] = '<small>Bitte hinterlegen Sie einen TXT-Record mit obigem Wert in den DNS-Einstellungen Ihrer Domainverwaltung.</small>';
$lang['edit']['relay_all_info'] = '<small>Wenn Sie <b>nicht</b> alle Empfänger-Adressen relayen möchten, müssen Sie eine ("blinde") Mailbox für jede Adresse, die relayt werden soll, erstellen.</small>';
$lang['edit']['full_name'] = 'Voller Name';
$lang['edit']['quota_mb'] = 'Speicherplatz (MiB)';
$lang['edit']['sender_acl'] = 'Darf Nachrichten versenden als';
$lang['edit']['sender_acl_info'] = 'Aliasse sind nicht abwählbar und vorausgewählt.';
$lang['edit']['dkim_txt_name'] = 'TXT-Record Name:';
$lang['edit']['dkim_txt_value'] = 'TXT-Record Wert:';
$lang['edit']['previous'] = 'Vorherige Seite';
$lang['edit']['unchanged_if_empty'] = 'Unverändert, wenn leer';
$lang['edit']['dont_check_sender_acl'] = 'Absender für Domain %s nicht prüfen';
$lang['add']['syncjob'] = 'Sync-Job erstellen';
$lang['add']['syncjob_hint'] = 'Passwörter werden unverschlüsselt abgelegt!';
$lang['add']['hostname'] = 'Servername';
$lang['add']['username'] = 'Benutzername';
$lang['add']['enc_method'] = 'Verschlüsselungsmethode';
+$lang['add']['maxage'] = 'Maximum age of messages that will be polled from remote (0 = ignore age)';
+$lang['add']['subfolder2'] = 'Sync into subfolder on destination';
$lang['add']['mins_interval'] = 'Abrufintervall (Minuten)';
$lang['add']['exclude'] = 'Elemente ausschließen (Regex)';
$lang['add']['delete2duplicates'] = 'Lösche Duplikate im Ziel';
$lang['add']['title'] = 'Objekt anlegen';
$lang['add']['domain'] = 'Domain';
$lang['add']['active'] = 'Aktiv';
$lang['add']['save'] = 'Änderungen speichern';
$lang['add']['description'] = 'Beschreibung:';
$lang['add']['max_aliases'] = 'Max. mögliche Aliasse:';
$lang['add']['max_mailboxes'] = 'Max. mögliche Mailboxen:';
$lang['add']['mailbox_quota_m'] = 'Max. Speicherplatz pro Mailbox (MiB):';
$lang['add']['domain_quota_m'] = 'Domain Speicherplatz gesamt (MiB):';
$lang['add']['backup_mx_options'] = 'Backup MX Optionen:';
$lang['add']['relay_all'] = 'Alle Empfänger-Adressen relayen';
$lang['add']['relay_domain'] = 'Relay Domain';
$lang['add']['relay_all_info'] = '<small>Wenn Sie <b>nicht</b> alle Empfänger-Adressen relayen möchten, müssen Sie eine Mailbox für jede Adresse, die relayt werden soll, erstellen.</small>';
$lang['add']['alias'] = 'Alias(se)';
$lang['add']['alias_spf_fail'] = '<b>Hinweis:</b> Wählen Sie ein externes Postfach als Ziel-Adresse, kann es unter Umständen zu fehlerhaften Spam-Erkennungen <b>beim Empfänger</b> kommen. Weitere Informationen zu diesem Thema finden Sie <a href="https://www.heinlein-support.de/blog/news/gmx-de-und-web-de-haben-mail-rejects-durch-spf/" target="_blank">hier.</a>';
$lang['add']['alias_address'] = 'Alias-Adresse(n):';
$lang['add']['alias_address_info'] = '<small>Vollständige E-Mail-Adresse(n) oder @example.com, um alle Nachrichten einer Domain weiterzuleiten. Getrennt durch Komma. <b>Nur eigene Domains</b>.</small>';
$lang['add']['alias_domain_info'] = '<small>Nur gültige Domains. Getrennt durch Komma.</small>';
$lang['add']['target_address'] = 'Ziel-Adresse(n):';
$lang['add']['target_address_info'] = '<small>Vollständige E-Mail-Adresse(n). Getrennt durch Komma.</small>';
$lang['add']['alias_domain'] = 'Alias-Domain';
$lang['add']['select'] = 'Bitte auswählen';
$lang['add']['target_domain'] = 'Ziel-Domain:';
$lang['add']['mailbox'] = 'Mailbox';
$lang['add']['mailbox_username'] = 'Benutzername (linker Teil der E-Mail-Adresse):';
$lang['add']['full_name'] = 'Vor- und Zuname:';
$lang['add']['quota_mb'] = 'Speicherplatz (MiB):';
$lang['add']['select_domain'] = 'Bitte zuerst eine Domain auswählen';
$lang['add']['password'] = 'Passwort:';
$lang['add']['password_repeat'] = 'Passwort (Wiederholung):';
$lang['add']['previous'] = 'Vorherige Seite';
$lang['add']['restart_sogo_hint'] = 'Der SOGo Container muss nach dem Hinzufügen einer neuen Domain neugestartet werden!';
$lang['login']['title'] = 'Anmeldung';
$lang['login']['administration'] = 'Administration';
$lang['login']['administration_details'] = 'Bitte verwenden Sie Ihre Administrator Anmeldedaten, um administrative Aufgaben wie das Anlegen einer Mailbox zu starten.';
$lang['login']['user_settings'] = 'Benutzereinstellungen';
$lang['login']['user_settings_details'] = 'Als E-Mail Benutzer vewenden Sie bitte Ihre E-Mail Anmeldedaten, um Passwörter zu verändern, temporäre (Spam-)Aliasse zu erstellen, den Spamfilter einzustellen oder auch um E-Mails zu importieren.';
$lang['login']['username'] = 'Benutzername';
$lang['login']['password'] = 'Passwort';
$lang['login']['reset_password'] = 'Mein Passwort zurücksetzen';
$lang['login']['login'] = 'Anmelden';
$lang['login']['previous'] = 'Vorherige Seite';
$lang['login']['delayed'] = 'Login wurde zur Sicherheit um %s Sekunde/n verzögert.';
$lang['login']['tfa'] = 'Zwei-Faktor-Authentifizierung';
$lang['login']['tfa_details'] = 'Bitte bestätigen Sie Ihr Einmalpasswort im folgenden Feld';
$lang['login']['confirm'] = 'Bestätigen';
$lang['login']['otp'] = 'Einmalpasswort';
$lang['login']['trash_login'] = 'Login verwerfen';
$lang['admin']['search_domain_da'] = 'Domains durchsuchen';
$lang['admin']['restrictions'] = 'Postifx Restriktionen';
$lang['admin']['rr'] = 'Postifx Recipient Restriktionen';
$lang['admin']['sr'] = 'Postifx Sender Restriktionen';
$lang['admin']['reset_defaults'] = 'Standard wiederherstellen';
$lang['admin']['r_inactive'] = 'Inaktive Restriktionen';
$lang['admin']['r_active'] = 'Aktive Restriktionen';
$lang['admin']['r_info'] = 'Ausgegraute/deaktivierte Elemente sind mailcow nicht bekannt und können nicht in die Liste inaktiver Elemente verschoben werden. Unbekannte Restriktionen werden trotzdem in Reihenfolge der Erscheinung gesetzt.<br />Sie können ein Element in der Datei <code>inc/vars.local.inc.php</code> als bekannt hinzufügen, um es zu bewegen.';
$lang['admin']['public_folders'] = 'Öffentliche Ordner';
$lang['admin']['public_folders_text'] = 'Ein Namespace "Public" wird erstellt. Der untenstehende Ordnername betrifft den Namen der automatisch erstellten Mailbox in diesem Namespace.';
$lang['admin']['public_folder_name'] = 'Ordnername <small>(alphanumerisch)</small>';
$lang['admin']['public_folder_enable'] = 'Öffentliche Ordner aktivieren';
$lang['admin']['public_folder_enable_text'] = 'Das Umschalten dieser Option entfernt keine Nachrichten aus den öffentlichen Ordnern.';
$lang['admin']['public_folder_pusf'] = 'Aktiviere "per-user seen flag"';
$lang['admin']['public_folder_pusf_text'] = 'Ein "per-user seen flag"-aktiviertes System markiert Nachrichten nicht als gelesen, wenn nur ein Benutzer sie gelesen hat. Jeder Benutzer verwaltet seine eigenen "seen flags".';
$lang['admin']['privacy'] = 'Datenschutz';
$lang['admin']['privacy_text'] = 'Diese Option aktiviert eine PCRE-Prüfung, die die Werte der Kopfzeilen "User-Agent", "X-Enigmail", "X-Mailer", "X-Originating-IP" sowie "Received: from" durch "localhost" bzw. "127.0.0.1" ersetzt.';
$lang['admin']['privacy_anon_mail'] = 'Anonymisiere ausgehende Kopfzeilen';
$lang['admin']['msg_size'] = 'Aktuelles Limit der Nachrichtengröße';
$lang['admin']['msg_size_limit'] = 'Aktuelles Limit der Nachrichtengröße';
$lang['admin']['msg_size_limit_details'] = 'Diese Einstellung wird Postfix und den Webserver neuladen.';
$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']['add'] = 'Hinzufügen';
$lang['admin']['configuration'] = 'Konfiguration';
$lang['admin']['password'] = 'Passwort';
$lang['admin']['password_repeat'] = 'Passwort (Wiederholung)';
$lang['admin']['active'] = 'Aktiv';
$lang['admin']['action'] = 'Aktion';
$lang['admin']['add_domain_admin'] = 'Domain-Administrator hinzufügen';
$lang['admin']['admin_domains'] = 'Domain-Zuweisungen';
$lang['admin']['domain_admins'] = 'Domain-Administratoren';
$lang['admin']['username'] = 'Benutzername';
$lang['admin']['edit'] = 'Bearbeiten';
$lang['admin']['remove'] = 'Entfernen';
$lang['admin']['save'] = 'Änderungen speichern';
$lang['admin']['admin'] = 'Administrator';
$lang['admin']['admin_details'] = 'Administrator bearbeiten';
$lang['admin']['unchanged_if_empty'] = 'Unverändert, wenn leer';
$lang['admin']['yes'] = '&#10004;';
$lang['admin']['no'] = '&#10008;';
$lang['admin']['access'] = 'Zugang';
$lang['admin']['invalid_max_msg_size'] = 'Invalid max. message size'; // NEEDS TRANSLATION
$lang['admin']['site_not_found'] = 'Kann mailcow Site-Konfiguration nicht finden';
$lang['admin']['public_folder_empty'] = 'Public folder name must not be empty'; // NEEDS TRANSLATION
$lang['admin']['set_rr_failed'] = 'Kann Postfix Restriktionen nicht setzen';
$lang['admin']['no_record'] = 'Kein Eintrag';
?>
diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php
index 3600d154..e764985c 100644
--- a/data/web/lang/lang.en.php
+++ b/data/web/lang/lang.en.php
@@ -1,410 +1,417 @@
<?php
/*
//
// English language file
//
*/
$lang['footer']['loading'] = "Please wait...";
$lang['header']['restart_sogo'] = 'Restart SOGo';
$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_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['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";
$lang['danger']['mailbox_quota_exceeds_domain_quota'] = "Max. quota exceeds domain quota limit";
$lang['danger']['object_is_not_numeric'] = "Value %s is not numeric";
$lang['success']['domain_added'] = "Added domain %s";
$lang['danger']['alias_empty'] = "Alias address must not be empty";
$lang['danger']['goto_empty'] = "Goto address must not be empty";
$lang['danger']['policy_list_from_exists'] = "A record with given name exists";
$lang['danger']['policy_list_from_invalid'] = "Record has invalid format";
$lang['danger']['whitelist_exists'] = "A whitelist record with that name exists";
$lang['danger']['whitelist_from_invalid'] = "Whitelist record has invalid format";
$lang['danger']['alias_invalid'] = "Alias address is invalid";
$lang['danger']['goto_invalid'] = "Goto address is invalid";
$lang['danger']['alias_domain_invalid'] = "Alias domain is invalid";
$lang['danger']['target_domain_invalid'] = "Goto domain is invalid";
$lang['danger']['object_exists'] = "Object %s already exists";
$lang['danger']['domain_exists'] = "Domain %s already exists";
$lang['danger']['alias_goto_identical'] = "Alias and goto address must not be identical";
$lang['danger']['aliasd_targetd_identical'] = "Alias domain must not be equal to target domain";
$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']['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";
$lang['danger']['aliasd_exists'] = "Alias domain already exists";
$lang['success']['aliasd_added'] = "Added alias domain %s";
$lang['success']['aliasd_modified'] = "Changes to alias domain %s have been saved";
$lang['success']['domain_modified'] = "Changes to domain %s have been saved";
$lang['success']['domain_admin_modified'] = "Changes to domain administrator %s have been saved";
$lang['success']['domain_admin_added'] = "Domain administrator %s has been added";
$lang['success']['changes_general'] = 'Changes have been saved';
$lang['success']['admin_modified'] = "Changes to administrator have been saved";
$lang['danger']['exit_code_not_null'] = "Error: Exit code was %d";
$lang['danger']['mailbox_not_available'] = "Mailbox not available";
$lang['danger']['username_invalid'] = "Username cannot be used";
$lang['danger']['password_mismatch'] = "Confirmation password is not identical";
$lang['danger']['password_complexity'] = "Password does not meet requirements";
$lang['danger']['password_empty'] = "Password must not be empty";
$lang['danger']['login_failed'] = "Login failed";
$lang['danger']['mailbox_invalid'] = "Mailbox name is invalid";
$lang['danger']['mailbox_invalid_suggest'] = 'Mailbox name is invalid, did you mean to type "%s"?';
$lang['info']['fetchmail_planned'] = "Task to fetch emails has been planned. Please check the process at a later time.";
$lang['danger']['fetchmail_source_empty'] = "Please define a source folder";
$lang['danger']['fetchmail_dest_empty'] = "Please define a target folder";
$lang['danger']['is_alias'] = "%s is already known as an alias address";
$lang['danger']['is_alias_or_mailbox'] = "%s is already known as an alias or a mailbox";
$lang['danger']['is_spam_alias'] = "%s is already known as a spam alias address";
$lang['danger']['quota_not_0_not_numeric'] = "Quota must be numeric and >= 0";
$lang['danger']['domain_not_found'] = "Domain not found.";
$lang['danger']['max_mailbox_exceeded'] = "Max. mailboxes exceeded (%d of %d)";
$lang['danger']['mailbox_quota_exceeded'] = "Quota exceeds the domain limit (max. %d MiB)";
$lang['danger']['mailbox_quota_left_exceeded'] = "Not enough space left (space left: %d MiB)";
$lang['success']['mailbox_added'] = "Mailbox %s has been added";
$lang['success']['domain_removed'] = "Domain %s has been removed";
$lang['success']['alias_removed'] = "Alias-Adresse %s has been removed";
$lang['success']['alias_domain_removed'] = "Alias domain %s has been removed";
$lang['success']['domain_admin_removed'] = "Domain administrator %s has been removed";
$lang['success']['mailbox_removed'] = "Mailbox %s has been removed";
$lang['danger']['max_quota_in_use'] = "Mailbox quota must be greater or equal to %d MiB";
$lang['danger']['domain_quota_m_in_use'] = "Domain quota must be greater or equal to %s MiB";
$lang['danger']['mailboxes_in_use'] = "Max. mailboxes must be greater or equal to %d";
$lang['danger']['aliases_in_use'] = "Max. aliases must be greater or equal to %d";
$lang['danger']['sender_acl_invalid'] = "Sender ACL value is invalid";
$lang['danger']['domain_not_empty'] = "Cannot remove non-empty domain";
$lang['warning']['spam_alias_temp_error'] = "Temporary error: Cannot add spam alias, please try again later.";
$lang['danger']['spam_alias_max_exceeded'] = "Max. allowed spam alias addresses exceeded";
$lang['danger']['fetchmail_active'] = "A process is already running, please wait for it to finish.";
$lang['danger']['validity_missing'] = 'Please assign a period of validity';
$lang['user']['on'] = "On";
$lang['user']['off'] = "Off";
$lang['user']['user_change_fn'] = "";
$lang['user']['user_settings'] = 'User settings';
$lang['user']['mailbox_settings'] = 'Mailbox settings';
$lang['user']['mailbox_details'] = 'Mailbox details';
$lang['user']['change_password'] = 'Change password';
$lang['user']['new_password'] = 'New password:';
$lang['user']['save_changes'] = 'Save changes';
$lang['user']['password_now'] = 'Current password (confirm changes):';
$lang['user']['new_password_repeat'] = 'Confirmation password (repeat):';
$lang['user']['new_password_description'] = 'Requirement: 6 characters long, letters and numbers.';
$lang['user']['did_you_know'] = '<b>Did you know?</b> You can use tags in your email address ("me+<b>privat</b>@example.com") to move messages to a folder automatically (example: "privat").';
$lang['user']['spam_aliases'] = 'Temporary email aliases';
$lang['user']['alias'] = 'Alias';
$lang['user']['aliases'] = 'Aliases';
+$lang['user']['domain_aliases'] = 'Domain alias addresses';
$lang['user']['is_catch_all'] = 'Catch-all for domain/s';
$lang['user']['aliases_also_send_as'] = 'Also allowed to send as';
$lang['user']['aliases_send_as_all'] = 'Do not check sender access for following domain/s';
$lang['user']['alias_create_random'] = 'Generate random alias';
$lang['user']['alias_extend_all'] = 'Extend aliases by 1 hour';
$lang['user']['alias_valid_until'] = 'Valid until';
$lang['user']['alias_remove_all'] = 'Remove all aliases';
$lang['user']['alias_time_left'] = 'Time left';
$lang['user']['alias_full_date'] = 'd.m.Y, H:i:s T';
$lang['user']['syncjob_full_date'] = 'd.m.Y, H:i:s T';
$lang['user']['alias_select_validity'] = 'Period of validity';
$lang['user']['sync_jobs'] = 'Sync jobs';
$lang['user']['hour'] = 'Hour';
$lang['user']['hours'] = 'Hours';
$lang['user']['day'] = 'Day';
$lang['user']['week'] = 'Week';
$lang['user']['weeks'] = 'Weeks';
$lang['user']['spamfilter'] = 'Spam filter';
$lang['user']['spamfilter_wl'] = 'Whitelist';
$lang['user']['spamfilter_wl_desc'] = 'Whitelisted email addresses to <b>never</b> classify as spam. Wildcards maybe used.';
$lang['user']['spamfilter_bl'] = 'Blacklist';
$lang['user']['spamfilter_bl_desc'] = 'Blacklisted email addresses to <b>always</b> classify as spam and reject. Wildcards maybe used.';
$lang['user']['spamfilter_behavior'] = 'Rating';
$lang['user']['spamfilter_table_rule'] = 'Rule';
$lang['user']['spamfilter_table_action'] = 'Action';
$lang['user']['spamfilter_table_empty'] = 'No data to display';
$lang['user']['spamfilter_table_remove'] = 'remove';
$lang['user']['spamfilter_table_add'] = 'Add item';
$lang['user']['spamfilter_default_score'] = 'Spam score:';
$lang['user']['spamfilter_green'] = 'Green: this message is not spam';
$lang['user']['spamfilter_yellow'] = 'Yellow: this message may be spam, will be tagged as spam and moved to your junk folder';
$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']['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';
$lang['user']['tls_enforce_in'] = 'Enforce TLS incoming';
$lang['user']['tls_enforce_out'] = 'Enforce TLS outgoing';
$lang['user']['no_record'] = 'No Record';
$lang['user']['misc_settings'] = 'Other profile settings';
$lang['user']['misc_delete_profile'] = 'Other profile settings';
$lang['user']['tag_handling'] = 'Set handling for tagged mail';
$lang['user']['tag_in_subfolder'] = 'In subfolder';
$lang['user']['tag_in_subject'] = 'In subject';
$lang['user']['tag_help_explain'] = 'In subfolder: a new subfolder named after the tag will be created below INBOX ("INBOX/Facebook").<br />
In subject: the tags name will be prepended to the mails subject, example: "[Facebook] Meine Neuigkeiten".';
$lang['user']['tag_help_example'] = 'Example for a tagged email address: ich<b>+Facebook</b>@example.org';
$lang['user']['encryption'] = 'Encyrption';
$lang['user']['username'] = 'Username';
$lang['user']['password'] = 'Password';
$lang['user']['last_run'] = 'Last run';
$lang['user']['excludes'] = 'Excludes';
$lang['user']['interval'] = 'Interval';
$lang['user']['active'] = 'Active';
$lang['user']['action'] = 'Action';
$lang['user']['edit'] = 'Edit';
$lang['user']['remove'] = 'Remove';
+$lang['user']['delete_now'] = 'Remove now';
$lang['user']['create_syncjob'] = 'Create new sync job';
$lang['start']['dashboard'] = '%s - dashboard';
$lang['start']['start_rc'] = 'Open Roundcube';
$lang['start']['start_sogo'] = 'Open SOGo';
$lang['start']['mailcow_apps_detail'] = 'Use a mailcow app to access your mails, calendar, contacts and more.';
$lang['start']['mailcow_panel'] = 'Start mailcow UI';
$lang['start']['mailcow_panel_description'] = 'The mailcow UI is available for administrators and mailbox users.';
$lang['start']['mailcow_panel_detail'] = '<b>Domain administrators</b> create, modify or delete mailboxes and aliases, change domains and read further information about their assigned domains.<br />
<b>Mailbox users</b> are able to create time-limited aliases (spam aliases), change their password and spam filter settings.';
$lang['start']['recommended_config'] = 'Recommended configuration (without ActiveSync)';
$lang['start']['imap_smtp_server'] = 'IMAP- and SMTP server data';
$lang['start']['imap_smtp_server_description'] = 'For the best experience we recommend to use <a href="%s" target="_blank"><b>Mozilla Thunderbird</b></a>.';
$lang['start']['imap_smtp_server_badge'] = 'Read/Write emails';
$lang['start']['imap_smtp_server_auth_info'] = 'Please use your full email address and the PLAIN authentication mechanism.<br />
Your login data will be encrypted by the server-side mandatory encryption.';
$lang['start']['managesieve'] = 'ManageSieve';
$lang['start']['managesieve_badge'] = 'Email filter';
$lang['start']['managesieve_description'] = 'Please use <b>Mozilla Thunderbird</b> with the <a style="text-decoration:none" target="_blank" href="%s"><b>nightly sieve extension</b></a>.<br />Start Thunderbird, open the add-on settings and drop the newly downloaded xpi file into the opened window.<br />The server name is <b>%s</b>, use port <b>4190</b> if you are asked for. The login data match your email login.';
$lang['start']['service'] = 'Service';
$lang['start']['encryption'] = 'Encryption method';
$lang['start']['help'] = 'Show/Hide help panel';
$lang['start']['hostname'] = 'Hostname';
$lang['start']['port'] = 'Port';
$lang['start']['footer'] = '';
$lang['header']['mailcow_settings'] = 'Configuration';
$lang['header']['administration'] = 'Administration';
$lang['header']['mailboxes'] = 'Mailboxes';
$lang['header']['user_settings'] = 'User settings';
$lang['header']['login'] = 'Login';
$lang['header']['logged_in_as_logout'] = 'Logged in as <b>%s</b> (logout)';
+$lang['header']['logged_in_as_logout_dual'] = 'Logged in as <b>%s <span class="text-info">[%s]</span></b>';
$lang['header']['locale'] = 'Language';
$lang['mailbox']['domain'] = 'Domain';
$lang['mailbox']['alias'] = 'Alias';
$lang['mailbox']['aliases'] = 'Aliases';
$lang['mailbox']['domains'] = 'Domains';
$lang['mailbox']['mailboxes'] = 'Mailboxes';
$lang['mailbox']['mailbox_quota'] = 'Max. size of a mailbox';
$lang['mailbox']['domain_quota'] = 'Quota';
$lang['mailbox']['active'] = 'Active';
$lang['mailbox']['action'] = 'Action';
$lang['mailbox']['ratelimit'] = 'Outgoing rate limit/h';
$lang['mailbox']['backup_mx'] = 'Backup MX';
$lang['mailbox']['domain_aliases'] = 'Domain aliases';
$lang['mailbox']['target_domain'] = 'Target domain';
$lang['mailbox']['target_address'] = 'Goto address';
$lang['mailbox']['username'] = 'Username';
$lang['mailbox']['fname'] = 'Full name';
$lang['mailbox']['filter_table'] = 'Filter table';
$lang['mailbox']['yes'] = '&#10004;';
$lang['mailbox']['no'] = '&#10008;';
$lang['mailbox']['quota'] = 'Quota';
$lang['mailbox']['in_use'] = 'In use (%)';
$lang['mailbox']['msg_num'] = 'Message #';
$lang['mailbox']['remove'] = 'Remove';
$lang['mailbox']['edit'] = 'Edit';
$lang['mailbox']['archive'] = 'Archive';
-$lang['mailbox']['no_record'] = 'No Record';
+$lang['mailbox']['no_record'] = 'No Record for object %s';
$lang['mailbox']['add_domain'] = 'Add domain';
$lang['mailbox']['add_domain_alias'] = 'Add domain alias';
$lang['mailbox']['add_mailbox'] = 'Add mailbox';
$lang['mailbox']['add_alias'] = 'Add alias';
$lang['info']['no_action'] = 'No action applicable';
$lang['delete']['title'] = 'Remove object';
$lang['delete']['remove_domain_warning'] = '<b>Warning:</b> You are about to remove the domain <b>%s</b>!';
$lang['delete']['remove_syncjob_warning'] = '<b>Warning:</b> You are about to remove a sync job for user <b>%s</b>!';
$lang['delete']['remove_domainalias_warning'] = '<b>Warning:</b> You are about to remove the domain alias <b>%s</b>!';
$lang['delete']['remove_domainadmin_warning'] = '<b>Warning:</b> You are about to remove the domain administrator <b>%s</b>!';
$lang['delete']['remove_alias_warning'] = '<b>Warning:</b> You are about to remove the alias address <b>%s</b>!';
$lang['delete']['remove_mailbox_warning'] = '<b>Warning:</b> You are about to remove the mailbox <b>%s</b>!';
$lang['delete']['remove_mailbox_details'] = 'The mailbox will be <b>purged permanently</b>!';
$lang['delete']['remove_domain_details'] = 'This also removes domain aliases.<br /><br /><b>A domain must be empty to be removed.</b>';
$lang['delete']['remove_syncjob_details'] = 'Objects from this sync job will not be pulled from the remote server anymore.';
$lang['delete']['remove_alias_details'] = 'Users will no longer be able to receive mail for or send mail from this address.</b>';
$lang['delete']['remove_button'] = 'Remove';
$lang['delete']['previous'] = 'Previous page';
$lang['edit']['syncjob'] = 'Edit sync job';
$lang['edit']['save'] = 'Save changes';
$lang['edit']['username'] = 'Save changes';
$lang['edit']['hostname'] = 'Hostname';
$lang['edit']['encryption'] = 'Encryption';
+$lang['edit']['maxage'] = 'Maximum age of messages in days that will be polled from remote<br /><small>(0 = ignore age)</small>';
+$lang['edit']['subfolder2'] = 'Sync into subfolder on destination<br /><small>(empty = do not use subfolder)</small>';
$lang['edit']['mins_interval'] = 'Interval (min)';
$lang['edit']['exclude'] = 'Exclude objects (regex)';
$lang['edit']['save'] = 'Save changes';
$lang['edit']['archive'] = 'Archive access';
$lang['edit']['max_mailboxes'] = 'Max. possible mailboxes';
$lang['edit']['title'] = 'Edit object';
$lang['edit']['target_address'] = 'Goto address/es <small>(comma-separated)</small>';
$lang['edit']['active'] = 'Active';
$lang['edit']['target_domain'] = 'Target domain';
$lang['edit']['password'] = 'Password';
$lang['edit']['ratelimit'] = 'Outgoing rate limit/h';
$lang['danger']['ratelimt_less_one'] = 'Outgoing rate limit/h must not be less than 1';
$lang['edit']['password_repeat'] = 'Confirmation password (repeat)';
$lang['edit']['domain_admin'] = 'Edit domain administrator';
$lang['edit']['domain'] = 'Edit domain';
$lang['edit']['alias_domain'] = 'Alias domain';
$lang['edit']['edit_alias_domain'] = 'Edit Alias domain';
$lang['edit']['domains'] = 'Domains';
$lang['edit']['destroy'] = 'Manual data input';
$lang['edit']['alias'] = 'Edit alias';
$lang['edit']['mailbox'] = 'Edit mailbox';
$lang['edit']['description'] = 'Description';
$lang['edit']['max_aliases'] = 'Max. aliases';
$lang['edit']['max_quota'] = 'Max. quota per mailbox (MiB)';
$lang['edit']['domain_quota'] = 'Domain quota';
$lang['edit']['backup_mx_options'] = 'Backup MX options';
$lang['edit']['relay_domain'] = 'Relay domain';
$lang['edit']['relay_all'] = 'Relay all recipients';
$lang['edit']['dkim_signature'] = 'DKIM signature';
$lang['edit']['dkim_record_info'] = '<small>Please add a TXT record with the given value to your DNS settings.</small>';
$lang['edit']['relay_all_info'] = '<small>If you choose <b>not</b> to relay all recipients, you will need to add a ("blind") mailbox for every single recipient that should be relayed.</small>';
$lang['edit']['full_name'] = 'Full name';
$lang['edit']['quota_mb'] = 'Quota (MiB)';
$lang['edit']['sender_acl'] = 'Allow to send as';
$lang['edit']['sender_acl_info'] = 'Aliases cannot be deselected.';
$lang['edit']['dkim_txt_name'] = 'TXT record name:';
$lang['edit']['dkim_txt_value'] = 'TXT record value:';
$lang['edit']['previous'] = 'Previous page';
$lang['edit']['unchanged_if_empty'] = 'If unchanged leave blank';
$lang['edit']['dont_check_sender_acl'] = 'Do not check sender for domain %s';
$lang['add']['syncjob'] = 'Add sync job';
$lang['add']['syncjob_hint'] = 'Be aware that passwords need to be saved plain-text!';
$lang['add']['hostname'] = 'Hostname';
$lang['add']['username'] = 'Username';
$lang['add']['enc_method'] = 'Encryption method';
$lang['add']['mins_interval'] = 'Polling interval (minutes)';
+$lang['add']['maxage'] = 'Maximum age of messages that will be polled from remote (0 = ignore age)';
+$lang['add']['subfolder2'] = 'Sync into subfolder on destination';
$lang['add']['exclude'] = 'Exclude objects (regex)';
$lang['add']['delete2duplicates'] = 'Delete duplicates on destination';
$lang['add']['title'] = 'Add object';
$lang['add']['domain'] = 'Domain';
$lang['add']['active'] = 'Active';
$lang['add']['save'] = 'Save changes';
$lang['add']['description'] = 'Description:';
$lang['add']['max_aliases'] = 'Max. possible aliases:';
$lang['add']['max_mailboxes'] = 'Max. possible mailboxes:';
$lang['add']['mailbox_quota_m'] = 'Max. quota per mailbox (MiB):';
$lang['add']['domain_quota_m'] = 'Total domain quota (MiB):';
$lang['add']['backup_mx_options'] = 'Backup MX options:';
$lang['add']['relay_all'] = 'Relay all recipients';
$lang['add']['relay_domain'] = 'Relay this domain';
$lang['add']['relay_all_info'] = '<small>If you choose <b>not</b> to relay all recipients, you will need to add a ("blind") mailbox for every single recipient that should be relayed.</small>';
$lang['add']['alias'] = 'Alias(es)';
$lang['add']['alias_spf_fail'] = '<b>Note:</b> If your chosen destination address is an external mailbox, the <b>receiving mailserver</b> may reject your message due to an SPF failure.</a>';
$lang['add']['alias_address'] = 'Alias address/es:';
$lang['add']['alias_address_info'] = '<small>Full email address/es or @example.com, to catch all messages for a domain (comma-separated). <b>mailcow domains only</b>.</small>';
$lang['add']['alias_domain_info'] = '<small>Valid domain names only (comma-separated).</small>';
$lang['add']['target_address'] = 'Goto addresses:';
$lang['add']['target_address_info'] = '<small>Full email address/es (comma-separated).</small>';
$lang['add']['alias_domain'] = 'Alias domain';
$lang['add']['select'] = 'Please select...';
$lang['add']['target_domain'] = 'Target domain:';
$lang['add']['mailbox'] = 'Mailbox';
$lang['add']['mailbox_username'] = 'Username (left part of an email address):';
$lang['add']['full_name'] = 'Full name:';
$lang['add']['quota_mb'] = 'Quota (MiB):';
$lang['add']['select_domain'] = 'Please select a domain first';
$lang['add']['password'] = 'Password:';
$lang['add']['password_repeat'] = 'Confirmation password (repeat):';
$lang['add']['previous'] = 'Previous page';
$lang['add']['restart_sogo_hint'] = 'You will need to restart the SOGo service container after adding a new domain!';
$lang['login']['title'] = 'Login';
$lang['login']['administration'] = 'Administration';
$lang['login']['administration_details'] = 'Please use your Administrator login to perform administrative tasks.';
$lang['login']['user_settings'] = 'User settings';
$lang['login']['user_settings_details'] = 'Mailbox users can use mailcow UI to change their passwords, create temporary aliases (spam aliases), adjust the spam filter behaviour or import messages from a remote IMAP server.';
$lang['login']['username'] = 'Username';
$lang['login']['password'] = 'Password';
$lang['login']['reset_password'] = 'Reset my password';
$lang['login']['login'] = 'Login';
$lang['login']['previous'] = "Previous page";
$lang['login']['delayed'] = 'Login was delayed by %s seconds.';
$lang['login']['tfa'] = "Two-factor authentication";
$lang['login']['tfa_details'] = "Please confirm your one-time password in the below field";
$lang['login']['confirm'] = "Confirm";
$lang['login']['otp'] = "One-time password";
$lang['login']['trash_login'] = "Trash login";
$lang['admin']['search_domain_da'] = 'Search domains';
$lang['admin']['restrictions'] = 'Postifx Restrictions';
$lang['admin']['rr'] = 'Postifx Recipient Restrictions';
$lang['admin']['sr'] = 'Postifx Sender Restrictions';
$lang['admin']['reset_defaults'] = 'Reset to defaults';
$lang['admin']['sr'] = 'Postifx Sender Restrictions';
$lang['admin']['r_inactive'] = 'Inactive restrictions';
$lang['admin']['r_active'] = 'Active restrictions';
$lang['admin']['r_info'] = 'Greyed out/disabled elements on the list of active restrictions are not known as valid restrictions to mailcow and cannot be moved. Unknown restrictions will be set in order of appearance anyway. <br />You can add new elements in <code>inc/vars.local.inc.php</code> to be able to toggle them.';
$lang['admin']['public_folders'] = 'Public Folders';
$lang['admin']['public_folders_text'] = 'A namespace "Public" is created. Below\'s public folder name indicates the name of the first auto-created mailbox within this namespace.';
$lang['admin']['public_folder_name'] = 'Folder name <small>(alphanumeric)</small>';
$lang['admin']['public_folder_enable'] = 'Enable public folder';
$lang['admin']['public_folder_enable_text'] = 'Toggling this option does not delete mail in any public folder.';
$lang['admin']['public_folder_pusf'] = 'Enable per-user seen flag';
$lang['admin']['public_folder_pusf_text'] = 'A "per-user seen flag"-enabled system will not mark a mail as read for User B, when User A has seen it, but User B did not.';
$lang['admin']['privacy'] = 'Privacy';
$lang['admin']['privacy_text'] = 'This option enables a PCRE table to remove "User-Agent", "X-Enigmail", "X-Mailer", "X-Originating-IP" and replaces "Received: from" headers with localhost/127.0.0.1.';
$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']['previous'] = 'Previous page';
$lang['admin']['quota_mb'] = 'Quota (MiB):';
$lang['admin']['sender_acl'] = 'Allow to send as:';
$lang['admin']['msg_size'] = 'Message size';
$lang['admin']['msg_size_limit'] = 'Message size limit now';
$lang['admin']['msg_size_limit_details'] = 'Applying a new limit will reload Postfix and the webserver.';
$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']['add'] = 'Add';
$lang['admin']['configuration'] = 'Configuration';
$lang['admin']['password'] = 'Password';
$lang['admin']['password_repeat'] = 'Confirmation password (repeat)';
$lang['admin']['active'] = 'Active';
$lang['admin']['action'] = 'Action';
$lang['admin']['add_domain_admin'] = 'Add Domain administrator';
$lang['admin']['admin_domains'] = 'Domain assignments';
$lang['admin']['domain_admins'] = 'Domain administrators';
$lang['admin']['username'] = 'Username';
$lang['admin']['edit'] = 'Edit';
$lang['admin']['remove'] = 'Remove';
$lang['admin']['save'] = 'Save changes';
$lang['admin']['admin'] = 'Administrator';
$lang['admin']['admin_details'] = 'Edit administrator details';
$lang['admin']['unchanged_if_empty'] = 'If unchanged leave blank';
$lang['admin']['yes'] = '&#10004;';
$lang['admin']['no'] = '&#10008;';
$lang['admin']['access'] = 'Access';
$lang['admin']['invalid_max_msg_size'] = 'Invalid max. message size';
$lang['admin']['site_not_found'] = 'Cannot locate mailcow site configuration';
$lang['admin']['public_folder_empty'] = 'Public folder name must not be empty';
$lang['admin']['set_rr_failed'] = 'Cannot set Postfix restrictions';
$lang['admin']['no_record'] = 'No Record';
?>
diff --git a/data/web/mailbox.php b/data/web/mailbox.php
index b04523f4..26c799b6 100644
--- a/data/web/mailbox.php
+++ b/data/web/mailbox.php
@@ -1,500 +1,354 @@
<?php
require_once "inc/prerequisites.inc.php";
if ($_SESSION['mailcow_cc_role'] == "admin" || $_SESSION['mailcow_cc_role'] == "domainadmin") {
require_once "inc/header.inc.php";
$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
?>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><?=$lang['mailbox']['domains'];?> <span class="badge" id="numRowsDomain"></span></h3>
<div class="pull-right">
<span class="clickable filter" data-toggle="tooltip" title="<?=$lang['mailbox']['filter_table'];?>" data-container="body">
<i class="glyphicon glyphicon-filter"></i>
</span>
<?php
if ($_SESSION['mailcow_cc_role'] == "admin"):
?>
<a href="/add.php?domain"><span class="glyphicon glyphicon-plus"></span></a>
<?php
endif;
?>
</div>
</div>
<div class="panel-body">
<input type="text" class="form-control" id="domaintable-filter" data-action="filter" data-filters="#domaintable" placeholder="Filter" />
</div>
<div class="table-responsive">
<table class="table table-striped sortable-theme-bootstrap" data-sortable id="domaintable">
<thead>
<tr>
<th class="sort-table" style="min-width: 86px;"><?=$lang['mailbox']['domain'];?></th>
<th class="sort-table" style="min-width: 81px;"><?=$lang['mailbox']['aliases'];?></th>
<th class="sort-table" style="min-width: 99px;"><?=$lang['mailbox']['mailboxes'];?></th>
<th class="sort-table" style="min-width: 172px;"><?=$lang['mailbox']['mailbox_quota'];?></th>
<th class="sort-table" style="min-width: 117px;"><?=$lang['mailbox']['domain_quota'];?></th>
<?php
if ($_SESSION['mailcow_cc_role'] == "admin"):
?>
<th class="sort-table" style="min-width: 105px;"><?=$lang['mailbox']['backup_mx'];?></th>
<?php
endif;
?>
<th class="sort-table" style="min-width: 76px;"><?=$lang['mailbox']['active'];?></th>
<th style="text-align: right; min-width: 200px;" data-sortable="false"><?=$lang['mailbox']['action'];?></th>
</tr>
</thead>
<tbody>
<?php
- try {
- $stmt = $pdo->prepare("SELECT
- `domain`,
- `aliases`,
- `mailboxes`,
- `maxquota` * 1048576 AS `maxquota`,
- `quota` * 1048576 AS `quota`,
- CASE `backupmx` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `backupmx`,
- CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
- FROM `domain` WHERE
- `domain` IN (
- SELECT `domain` FROM `domain_admins` WHERE `username`= :username AND `active`='1'
- )
- OR 'admin'= :admin");
- $stmt->execute(array(
- ':username' => $_SESSION['mailcow_cc_username'],
- ':admin' => $_SESSION['mailcow_cc_role'],
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- if(!empty($rows)):
- while($row = array_shift($rows)):
- try {
- $stmt = $pdo->prepare("SELECT COUNT(*) AS `count` FROM `alias`
- WHERE `domain`= :domain
- AND `address` NOT IN (
- SELECT `username` FROM `mailbox`)");
- $stmt->execute(array(':domain' => $row['domain']));
- $AliasData = $stmt->fetch(PDO::FETCH_ASSOC);
-
- $stmt = $pdo->prepare("SELECT
- COUNT(*) AS `count`,
- COALESCE(SUM(`quota`), '0') AS `quota`
- FROM `mailbox`
- WHERE `domain` = :domain");
- $stmt->execute(array(':domain' => $row['domain']));
- $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
+ $domains = mailbox_get_domains();
+ if (!empty($domains)):
+ foreach ($domains as $domain):
+ $domaindata = mailbox_get_domain_details($domain);
?>
<tr id="data">
- <td><?=htmlspecialchars($row['domain']);?></td>
- <td><?=intval($AliasData['count']);?> / <?=intval($row['aliases']);?></td>
- <td><?=$MailboxData['count'];?> / <?=$row['mailboxes'];?></td>
- <td><?=formatBytes(intval($row['maxquota']), 2);?></td>
- <td><?=formatBytes(intval($MailboxData['quota']), 2);?> / <?=formatBytes(intval($row['quota']));?></td>
+ <td><?=htmlspecialchars($domaindata['domain_name']);?></td>
+ <td><?=$domaindata['aliases_in_domain'];?> / <?=$domaindata['max_num_aliases_for_domain'];?></td>
+ <td><?=$domaindata['mboxes_in_domain'];?> / <?=$domaindata['max_num_mboxes_for_domain'];?></td>
+ <td><?=$domaindata['max_quota_for_mbox'];?></td>
+ <td><?=$domaindata['quota_used_in_domain'];?> / <?=$domaindata['max_quota_for_domain'];?></td>
<?php
if ($_SESSION['mailcow_cc_role'] == "admin"):
?>
- <td><?=$row['backupmx'];?></td>
+ <td><?=$domaindata['backupmx'];?></td>
<?php
endif;
?>
- <td><?=$row['active'];?></td>
+ <td><?=$domaindata['active'];?></td>
<?php
if ($_SESSION['mailcow_cc_role'] == "admin"):
?>
<td style="text-align: right;">
<div class="btn-group">
- <a href="/edit.php?domain=<?=urlencode($row['domain']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
- <a href="/delete.php?domain=<?=urlencode($row['domain']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['mailbox']['remove'];?></a>
+ <a href="/edit.php?domain=<?=urlencode($domaindata['domain_name']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
+ <a href="/delete.php?domain=<?=urlencode($domaindata['domain_name']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['mailbox']['remove'];?></a>
</div>
</td>
<?php
else:
?>
<td style="text-align: right;">
<div class="btn-group">
- <a href="/edit.php?domain=<?=urlencode($row['domain']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
+ <a href="/edit.php?domain=<?=urlencode($domaindata['domain_name']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
</div>
</td>
</tr>
- <?php
- endif;
- endwhile;
- else:
- ?>
- <tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['no_record'];?></td></tr>
- <?php
- endif;
+ <?php
+ endif;
+ endforeach;
+ else:
?>
+ <tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['no_record'];?></td></tr>
+ <?php
+ endif;
+ ?>
</tbody>
<?php
if ($_SESSION['mailcow_cc_role'] == "admin"):
?>
<tfoot>
<tr id="no-data">
<td colspan="8" style="text-align: center; font-style: normal; border-top: 1px solid #e7e7e7;">
<a href="/add.php?domain"><?=$lang['mailbox']['add_domain'];?></a>
</td>
</tr>
</tfoot>
<?php
endif;
?>
</table>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><?=$lang['mailbox']['domain_aliases'];?> <span class="badge" id="numRowsDomainAlias"></span></h3>
<div class="pull-right">
<span class="clickable filter" data-toggle="tooltip" title="<?=$lang['mailbox']['filter_table'];?>" data-container="body">
<i class="glyphicon glyphicon-filter"></i>
</span>
<a href="/add.php?aliasdomain"><span class="glyphicon glyphicon-plus"></span></a>
</div>
</div>
<div class="panel-body">
<input type="text" class="form-control" id="domainaliastable-filter" data-action="filter" data-filters="#domainaliastable" placeholder="Filter" />
</div>
<div class="table-responsive">
<table class="table table-striped sortable-theme-bootstrap" data-sortable id="domainaliastable">
<thead>
<tr>
<th class="sort-table" style="min-width: 67px;"><?=$lang['mailbox']['alias'];?></th>
<th class="sort-table" style="min-width: 127px;"><?=$lang['mailbox']['target_domain'];?></th>
<th class="sort-table" style="min-width: 76px;"><?=$lang['mailbox']['active'];?></th>
<th style="text-align: right; min-width: 200px;" data-sortable="false"><?=$lang['mailbox']['action'];?></th>
</tr>
</thead>
<tbody>
<?php
- try {
- $stmt = $pdo->prepare("SELECT
- `alias_domain`,
- `target_domain`,
- CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
- FROM `alias_domain`
- WHERE `target_domain` IN (
- SELECT `domain` FROM `domain_admins`
- WHERE `username`= :username
- AND `active`='1'
- )
- OR 'admin' = :admin");
- $stmt->execute(array(
- ':username' => $_SESSION['mailcow_cc_username'],
- ':admin' => $_SESSION['mailcow_cc_role'],
- ));
- $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)):
- ?>
- <tr id="data">
- <td><?=htmlspecialchars($row['alias_domain']);?></td>
- <td><?=htmlspecialchars($row['target_domain']);?></td>
- <td><?=$row['active'];?></td>
- <td style="text-align: right;">
- <div class="btn-group">
- <a href="/edit.php?aliasdomain=<?=urlencode($row['alias_domain']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
- <a href="/delete.php?aliasdomain=<?=urlencode($row['alias_domain']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['mailbox']['remove'];?></a>
- </div>
- </td>
- </tr>
- <?php
- endwhile;
- else:
+ foreach (mailbox_get_domains() as $domain) {
+ $alias_domains = mailbox_get_alias_domains($domain);
+ if (!empty($alias_domains)) {
+ foreach ($alias_domains as $alias_domain) {
+ $aliasdomaindata = mailbox_get_alias_domain_details($alias_domain);
+ ?>
+ <tr id="data">
+ <td><?=htmlspecialchars($aliasdomaindata['alias_domain']);?></td>
+ <td><?=htmlspecialchars($aliasdomaindata['target_domain']);?></td>
+ <td><?=$aliasdomaindata['active'];?></td>
+ <td style="text-align: right;">
+ <div class="btn-group">
+ <a href="/edit.php?aliasdomain=<?=urlencode($aliasdomaindata['alias_domain']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
+ <a href="/delete.php?aliasdomain=<?=urlencode($aliasdomaindata['alias_domain']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['mailbox']['remove'];?></a>
+ </div>
+ </td>
+ </tr>
+ <?php
+ }
+ }
+ else {
?>
- <tr id="no-data"><td colspan="4" 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;"><?=sprintf($lang['mailbox']['no_record'], $domain);?></td></tr>
<?php
- endif;
- ?>
+ }
+ }
+ ?>
</tbody>
<tfoot>
<tr id="no-data">
<td colspan="8" style="text-align: center; border-top: 1px solid #e7e7e7;">
<a href="/add.php?aliasdomain"><?=$lang['mailbox']['add_domain_alias'];?></a>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><?=$lang['mailbox']['mailboxes'];?> <span class="badge" id="numRowsMailbox"></span></h3>
<div class="pull-right">
<span class="clickable filter" data-toggle="tooltip" title="<?=$lang['mailbox']['filter_table'];?>" data-container="body">
<i class="glyphicon glyphicon-filter"></i>
</span>
<a href="/add.php?mailbox"><span class="glyphicon glyphicon-plus"></span></a>
</div>
</div>
<div class="panel-body">
<input type="text" class="form-control" id="mailboxtable-filter" data-action="filter" data-filters="#mailboxtable" placeholder="Filter" />
</div>
<div class="table-responsive">
<table class="table table-striped sortable-theme-bootstrap" data-sortable id="mailboxtable">
<thead>
<tr>
<th class="sort-table" style="min-width: 100px;"><?=$lang['mailbox']['username'];?></th>
<th class="sort-table" style="min-width: 98px;"><?=$lang['mailbox']['fname'];?></th>
<th class="sort-table" style="min-width: 86px;"><?=$lang['mailbox']['domain'];?></th>
<th class="sort-table" style="min-width: 75px;"><?=$lang['mailbox']['quota'];?></th>
<th class="sort-table" style="min-width: 99px;"><?=$lang['mailbox']['in_use'];?></th>
<th class="sort-table" style="min-width: 100px;"><?=$lang['mailbox']['msg_num'];?></th>
<th class="sort-table" style="min-width: 76px;"><?=$lang['mailbox']['active'];?></th>
<th style="text-align: right; min-width: 200px;" data-sortable="false"><?=$lang['mailbox']['action'];?></th>
</tr>
</thead>
<tbody>
<?php
- try {
- $stmt = $pdo->prepare("SELECT
- `domain`.`backupmx`,
- `mailbox`.`username`,
- `mailbox`.`name`,
- CASE `mailbox`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
- `mailbox`.`domain`,
- `mailbox`.`quota`,
- `quota2`.`bytes`,
- `quota2`.`messages`
- FROM `mailbox`, `quota2`, `domain`
- WHERE (`mailbox`.`username` = `quota2`.`username`)
- AND (`domain`.`domain` = `mailbox`.`domain`)
- AND (`mailbox`.`domain` IN (
- SELECT `domain` FROM `domain_admins`
- WHERE `username`= :username
- AND `active`='1'
- )
- OR 'admin' = :admin)");
- $stmt->execute(array(
- ':username' => $_SESSION['mailcow_cc_username'],
- ':admin' => $_SESSION['mailcow_cc_role'],
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- if(!empty($rows)):
- while($row = array_shift($rows)):
+ foreach (mailbox_get_domains() as $domain) {
+ $mailboxes = mailbox_get_mailboxes($domain);
+ if (!empty($mailboxes)) {
+ foreach ($mailboxes as $mailbox) {
+ $mailboxdata = mailbox_get_mailbox_details($mailbox);
?>
<tr id="data">
- <?php
- if ($row['backupmx'] == "0"):
- ?>
- <td><?=htmlspecialchars($row['username']);?></td>
- <?php
- else:
- ?>
- <td><span data-toggle="tooltip" title="Relayed"><i class="glyphicon glyphicon-forward"></i> <?=htmlspecialchars($row['username']);?></span></td>
- <?php
- endif;
- ?>
- <td><?=htmlspecialchars($row['name'], ENT_QUOTES, 'UTF-8');?></td>
- <td><?=htmlspecialchars($row['domain']);?></td>
- <td><?=formatBytes(intval($row['bytes']), 2);?> / <?=formatBytes(intval($row['quota']), 2);?></td>
+ <td><?=($mailboxdata['is_relayed'] == "0") ? htmlspecialchars($mailboxdata['username']) : '<span data-toggle="tooltip" title="Relayed"><i class="glyphicon glyphicon-forward"></i>' . htmlspecialchars($mailboxdata['username']) . '</span>';?></td>
+ <td><?=htmlspecialchars($mailboxdata['name'], ENT_QUOTES, 'UTF-8');?></td>
+ <td><?=htmlspecialchars($mailboxdata['domain']);?></td>
+ <td><?=$mailboxdata['quota_used'];?> / <?=$mailboxdata['quota'];?></td>
<td style="min-width:120px;">
- <?php
- $percentInUse = round((intval($row['bytes']) / intval($row['quota'])) * 100);
- if ($percentInUse >= 90) {
- $pbar = "progress-bar-danger";
- }
- elseif ($percentInUse >= 75) {
- $pbar = "progress-bar-warning";
- }
- else {
- $pbar = "progress-bar-success";
- }
- ?>
<div class="progress">
- <div class="progress-bar <?=$pbar;?>" role="progressbar" aria-valuenow="<?=$percentInUse;?>" aria-valuemin="0" aria-valuemax="100" style="min-width:2em;width: <?=$percentInUse;?>%;">
- <?=$percentInUse;?>%
+ <div class="progress-bar progress-bar-<?=$mailboxdata['percent_class'];?>" role="progressbar" aria-valuenow="<?=$mailboxdata['percent_in_use'];?>" aria-valuemin="0" aria-valuemax="100" style="min-width:2em;width: <?=$mailboxdata['percent_in_use'];?>%;">
+ <?=$mailboxdata['percent_in_use'];?>%
</div>
</div>
</td>
- <td><?=$row['messages'];?></td>
- <td><?=$row['active'];?></td>
+ <td><?=$mailboxdata['messages'];?></td>
+ <td><?=$mailboxdata['active'];?></td>
<td style="text-align: right;">
<div class="btn-group">
- <a href="/edit.php?mailbox=<?=urlencode($row['username']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
- <a href="/delete.php?mailbox=<?=urlencode($row['username']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['mailbox']['remove'];?></a>
+ <a href="/edit.php?mailbox=<?=urlencode($mailboxdata['username']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
+ <a href="/delete.php?mailbox=<?=urlencode($mailboxdata['username']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['mailbox']['remove'];?></a>
+ <?php if ($_SESSION['mailcow_cc_role'] == "admin"): ?>
+ <a href="/index.php?duallogin=<?=urlencode($mailboxdata['username']);?>" class="btn btn-xs btn-success"><span class="glyphicon glyphicon-user"></span> Login</a>
+ <?php endif; ?>
</div>
</td>
</tr>
<?php
- endwhile;
- else:
- ?>
- <tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['no_record'];?></td></tr>
- <?php
- endif;
+ }
+ }
+ else {
+ ?>
+ <tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=sprintf($lang['mailbox']['no_record'], $domain);?></td></tr>
+ <?php
+ }
+ }
?>
</tbody>
<tfoot>
<tr id="no-data">
<td colspan="8" style="text-align: center; border-top: 1px solid #e7e7e7;">
<a href="/add.php?mailbox"><?=$lang['mailbox']['add_mailbox'];?></a>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><?=$lang['mailbox']['aliases'];?> <span class="badge" id="numRowsAlias"></span></h3>
<div class="pull-right">
<span class="clickable filter" data-toggle="tooltip" title="<?=$lang['mailbox']['filter_table'];?>" data-container="body">
<i class="glyphicon glyphicon-filter"></i>
</span>
<a href="/add.php?alias"><span class="glyphicon glyphicon-plus"></span></a>
</div>
</div>
<div class="panel-body">
<input type="text" class="form-control" id="aliastable-filter" data-action="filter" data-filters="#aliastable" placeholder="Filter" />
</div>
<div class="table-responsive">
<table class="table table-striped sortable-theme-bootstrap" data-sortable id="aliastable">
<thead>
<tr>
<th class="sort-table" style="min-width: 67px;"><?=$lang['mailbox']['alias'];?></th>
<th class="sort-table" style="min-width: 119px;"><?=$lang['mailbox']['target_address'];?></th>
<th class="sort-table" style="min-width: 86px;"><?=$lang['mailbox']['domain'];?></th>
<th class="sort-table" style="min-width: 76px;"><?=$lang['mailbox']['active'];?></th>
<th style="text-align: right; min-width: 200px;" data-sortable="false"><?=$lang['mailbox']['action'];?></th>
</tr>
</thead>
<tbody>
<?php
- try {
- $stmt = $pdo->prepare("SELECT
- `address`,
- `goto`,
- `domain`,
- CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
- FROM alias
- WHERE (
- `address` NOT IN (
- SELECT `username` FROM `mailbox`
- )
- AND `address` != `goto`
- ) AND (`domain` IN (
- SELECT `domain` FROM `domain_admins`
- WHERE `username` = :username
- AND active='1'
- )
- OR 'admin' = :admin)");
- $stmt->execute(array(
- ':username' => $_SESSION['mailcow_cc_username'],
- ':admin' => $_SESSION['mailcow_cc_role'],
- ));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- if(!empty($rows)):
- while($row = array_shift($rows)):
+ foreach (mailbox_get_domains() as $domain) {
+ $aliases = mailbox_get_aliases($domain);
+ if (!empty($aliases)) {
+ foreach ($aliases as $alias) {
+ $aliasdata = mailbox_get_alias_details($alias);
?>
<tr id="data">
<td>
- <?php
- if(!filter_var($row['address'], FILTER_VALIDATE_EMAIL)):
- ?>
- <span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span> Catch-all @<?=htmlspecialchars($row['domain']);?>
- <?php
- else:
- echo htmlspecialchars($row['address']);
- endif;
- ?>
+ <?= ($aliasdata['is_catch_all'] == "1") ? '<span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span> Catch-all ' . htmlspecialchars($aliasdata['address']) : htmlspecialchars($aliasdata['address']); ?>
</td>
<td>
<?php
- foreach(explode(",", $row['goto']) as $goto) {
+ foreach(explode(",", $aliasdata['goto']) as $goto) {
echo nl2br(htmlspecialchars($goto.PHP_EOL));
}
?>
</td>
- <td><?=htmlspecialchars($row['domain']);?></td>
- <td><?=$row['active'];?></td>
+ <td><?=htmlspecialchars($aliasdata['domain']);?></td>
+ <td><?=$aliasdata['active'];?></td>
<td style="text-align: right;">
<div class="btn-group">
- <a href="/edit.php?alias=<?=urlencode($row['address']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
- <a href="/delete.php?alias=<?=urlencode($row['address']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['mailbox']['remove'];?></a>
+ <a href="/edit.php?alias=<?=urlencode($aliasdata['address']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
+ <a href="/delete.php?alias=<?=urlencode($aliasdata['address']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['mailbox']['remove'];?></a>
</div>
</td>
</tr>
- <?php
- endwhile;
- else:
- ?>
- <tr id="no-data"><td colspan="5" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['no_record'];?></td></tr>
- <?php
- endif;
- ?>
+ <?php
+ }
+ }
+ else {
+ ?>
+ <tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=sprintf($lang['mailbox']['no_record'], $domain);?></td></tr>
+ <?php
+ }
+ }
+ ?>
</tbody>
<tfoot>
<tr id="no-data">
<td colspan="8" style="text-align: center; border-top: 1px solid #e7e7e7;">
<a href="/add.php?alias"><?=$lang['mailbox']['add_alias'];?></a>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
</div> <!-- /container -->
<script src="js/sorttable.js"></script>
<script src="js/mailbox.js"></script>
<?php
require_once("inc/footer.inc.php");
} else {
header('Location: /');
exit();
}
?>
diff --git a/data/web/user.php b/data/web/user.php
index 7d55d0c1..33e26e81 100644
--- a/data/web/user.php
+++ b/data/web/user.php
@@ -1,466 +1,484 @@
<?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'];
$username = $_SESSION['mailcow_cc_username'];
$get_tls_policy = get_tls_policy($_SESSION['mailcow_cc_username']);
?>
<div class="container">
<h3><?=$lang['user']['mailbox_settings'];?></h3>
<div class="panel panel-default">
<div class="panel-heading"><?=$lang['user']['mailbox_details'];?></div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="post" autocomplete="off">
<div class="form-group">
<div class="col-sm-offset-3 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="togglePwNew" id="togglePwNew"> <?=$lang['user']['change_password'];?></label>
</div>
</div>
</div>
<div class="passFields">
<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" disabled="disabled" 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" disabled="disabled" autocomplete="off" required>
<p class="help-block"><?=$lang['user']['new_password_description'];?></p>
</div>
</div>
<hr>
</div>
<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 type="submit" name="trigger_set_user_account" class="btn btn-success btn-default"><?=$lang['user']['save_changes'];?></button>
</div>
</div>
</form>
<hr>
<?php // Get user information about aliases
- $get_user_object_info = user_object_info('get');?>
+ $user_get_alias_details = user_get_alias_details($username);?>
<div class="row">
<div class="col-md-3 col-xs-5 text-right"><?=$lang['user']['aliases'];?>:</div>
<div class="col-md-9 col-xs-7">
- <p><?=$get_user_object_info['aliases'];?></p>
+ <p><?=$user_get_alias_details['aliases'];?></p>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-3 col-xs-5 text-right"><?=$lang['user']['domain_aliases'];?>:</div>
+ <div class="col-md-9 col-xs-7">
+ <p><?=$user_get_alias_details['ad_alias'];?></p>
</div>
</div>
<div class="row">
<div class="col-md-3 col-xs-5 text-right"><?=$lang['user']['aliases_also_send_as'];?>:</div>
<div class="col-md-9 col-xs-7">
- <p><?=$get_user_object_info['aliases_also_send_as'];?></p>
+ <p><?=$user_get_alias_details['aliases_also_send_as'];?></p>
</div>
</div>
<div class="row">
<div class="col-md-3 col-xs-5 text-right"><?=$lang['user']['aliases_send_as_all'];?>:</div>
<div class="col-md-9 col-xs-7">
- <p><?=$get_user_object_info['aliases_send_as_all'];?></p>
+ <p><?=$user_get_alias_details['aliases_send_as_all'];?></p>
</div>
</div>
<div class="row">
<div class="col-md-3 col-xs-5 text-right"><?=$lang['user']['is_catch_all'];?>:</div>
<div class="col-md-9 col-xs-7">
- <p><?=$get_user_object_info['is_catch_all'];?></p>
+ <p><?=$user_get_alias_details['is_catch_all'];?></p>
</div>
</div>
<hr>
<?php // Show tagging options ?>
<form class="form-horizontal" role="form" method="post">
<?php $get_tagging_options = tagging_options('get');?>
<div class="row">
<div class="col-md-3 col-xs-5 text-right"><?=$lang['user']['tag_handling'];?>:</div>
<div class="col-md-9 col-xs-7">
<input type="hidden" name="trigger_set_tagging_options" value="1">
<select name="tagged_mail_handler" class="selectpicker" onchange="this.form.submit()">
<option value="subfolder" <?=($get_tagging_options == "0") ? 'selected' : null; ?>><?=$lang['user']['tag_in_subfolder'];?></option>
<option value="subject" <?=($get_tagging_options == "1") ? 'selected' : null; ?>><?=$lang['user']['tag_in_subject'];?></option>
</select>
<p class="help-block"><?=$lang['user']['tag_help_explain'];?></p>
<p class="help-block"><?=$lang['user']['tag_help_example'];?></p>
</div>
</div>
</form>
</div>
</div>
<!-- Nav tabs -->
<ul class="nav nav-pills nav-justified" role="tablist">
<li role="presentation" class="active"><a href="#SpamAliases" aria-controls="SpamAliases" role="tab" data-toggle="tab"><?=$lang['user']['spam_aliases'];?></a></li>
<li role="presentation"><a href="#Spamfilter" aria-controls="Spamfilter" role="tab" data-toggle="tab"><?=$lang['user']['spamfilter'];?></a></li>
<li role="presentation"><a href="#TLSPolicy" aria-controls="TLSPolicy" role="tab" data-toggle="tab"><?=$lang['user']['tls_policy'];?></a></li>
<li role="presentation"><a href="#Syncjobs" aria-controls="Syncjobs" role="tab" data-toggle="tab"><?=$lang['user']['sync_jobs'];?></a></li>
</ul>
<hr>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="SpamAliases">
- <form class="form-horizontal" role="form" method="post">
- <div class="table-responsive">
- <table class="table table-striped sortable-theme-bootstrap" data-sortable id="timelimitedaliases">
- <thead>
- <tr>
- <th class="sort-table" style="min-width: 96px;"><?=$lang['user']['alias'];?></th>
- <th class="sort-table" style="min-width: 135px;"><?=$lang['user']['alias_valid_until'];?></th>
- </tr>
- </thead>
- <tbody>
+ <div class="row">
+ <div class="col-xs-5">
+ <p><b><?=$lang['user']['alias'];?></b></p>
+ </div>
+ <div class="col-xs-4">
+ <p><b><?=$lang['user']['alias_valid_until'];?></b></p>
+ </div>
+ <div class="col-xs-3">
+ <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)):
?>
- <tr id="data">
- <td><?=htmlspecialchars($row['address']);?></td>
- <td><?=htmlspecialchars(date($lang['user']['alias_full_date'], $row['validity']));?></td>
- </tr>
+ <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;
else:
?>
- <tr id="no-data"><td colspan="2" style="text-align: center; font-style: italic;"><?=$lang['user']['no_record'];?></td></tr>
+ <div class="col-xs-12">
+ <center><i><?=$lang['user']['no_record'];?></i></center>
+ </div>
<?php
endif;
?>
- </tbody>
- </table>
</div>
+ <form class="form-horizontal" role="form" method="post">
<div class="form-group">
<div class="col-sm-9">
<select id="validity" name="validity" title="<?=$lang['user']['alias_select_validity'];?>">
<option value="1">1 <?=$lang['user']['hour'];?></option>
<option value="6">6 <?=$lang['user']['hours'];?></option>
<option value="24">1 <?=$lang['user']['day'];?></option>
<option value="168">1 <?=$lang['user']['week'];?></option>
<option value="672">4 <?=$lang['user']['weeks'];?></option>
</select>
<button type="submit" id="trigger_set_time_limited_aliases" name="trigger_set_time_limited_aliases" value="generate" class="btn btn-success"><?=$lang['user']['alias_create_random'];?></button>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
- <button style="border-color:#f5f5f5;background:none;color:red" type="submit" name="trigger_set_time_limited_aliases" value="delete" class="btn btn-sm">
+ <button style="border-color:#f5f5f5;background:none;color:red" type="submit" name="trigger_set_time_limited_aliases" value="deleteall" class="btn btn-sm">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span> <?=$lang['user']['alias_remove_all'];?>
</button>
<button style="border-color:#f5f5f5;background:none;color:grey" type="submit" name="trigger_set_time_limited_aliases" value="extend" class="btn btn-sm">
<span class="glyphicon glyphicon-hourglass" aria-hidden="true"></span> <?=$lang['user']['alias_extend_all'];?>
</button>
</div>
</div>
</form>
</div>
<div role="tabpanel" class="tab-pane" id="Spamfilter">
<h4><?=$lang['user']['spamfilter_behavior'];?></h4>
<form class="form-horizontal" role="form" method="post">
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input name="score" id="score" type="text"
data-provide="slider"
data-slider-min="1"
data-slider-max="30"
data-slider-step="0.5"
data-slider-range="true"
data-slider-tooltip='always'
data-slider-id="slider1"
data-slider-value="[<?=get_spam_score($_SESSION['mailcow_cc_username']);?>]"
data-slider-step="1" />
<br /><br />
<ul>
<li><?=$lang['user']['spamfilter_green'];?></li>
<li><?=$lang['user']['spamfilter_yellow'];?></li>
<li><?=$lang['user']['spamfilter_red'];?></li>
</ul>
<p><i><?=$lang['user']['spamfilter_default_score'];?> 5:15</i></p>
<p><?=$lang['user']['spamfilter_hint'];?></p>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" id="trigger_set_spam_score" name="trigger_set_spam_score" class="btn btn-success"><?=$lang['user']['save_changes'];?></button>
</div>
</div>
</form>
<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
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):
?>
<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;
?>
<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">
</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
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):
?>
<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;
?>
<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">
</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>
</div>
<div role="tabpanel" class="tab-pane" id="TLSPolicy">
<form class="form-horizontal" role="form" method="post">
<p class="help-block"><?=$lang['user']['tls_policy_warning'];?></p>
<div class="form-group">
<div class="col-sm-6">
<div class="checkbox">
<h4><span class="glyphicon glyphicon-download" aria-hidden="true"></span> <?=$lang['user']['tls_enforce_in'];?></h4>
<input type="checkbox" id="tls_in" name="tls_in" <?=($get_tls_policy['tls_enforce_in'] == "1") ? "checked" : null;?> data-on-text="<?=$lang['user']['on'];?>" data-off-text="<?=$lang['user']['off'];?>">
</div>
</div>
<div class="col-sm-6">
<div class="checkbox">
<h4><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> <?=$lang['user']['tls_enforce_out'];?></h4>
<input type="checkbox" id="tls_out" name="tls_out" <?=($get_tls_policy['tls_enforce_out'] == "1") ? "checked" : null;?> data-on-text="<?=$lang['user']['on'];?>" data-off-text="<?=$lang['user']['off'];?>">
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<button type="submit" id="trigger_set_tls_policy" name="trigger_set_tls_policy" class="btn btn-default"><?=$lang['user']['save_changes'];?></button>
</div>
</div>
</form>
</div>
<div role="tabpanel" class="tab-pane" id="Syncjobs">
+ <div class="table-responsive">
<table class="table table-striped sortable-theme-bootstrap" data-sortable id="timelimitedaliases">
<thead>
<tr>
<th class="sort-table" style="min-width: 96px;">Server:Port</th>
<th class="sort-table" style="min-width: 96px;"><?=$lang['user']['encryption'];?></th>
<th class="sort-table" style="min-width: 96px;"><?=$lang['user']['username'];?></th>
- <th class="sort-table" style="min-width: 35px;"><?=$lang['user']['excludes'];?></th>
+ <th class="sort-table" style="min-width: 96px;"><?=$lang['user']['excludes'];?></th>
<th class="sort-table" style="min-width: 35px;"><?=$lang['user']['interval'];?></th>
<th class="sort-table" style="min-width: 35px;"><?=$lang['user']['last_run'];?></th>
<th class="sort-table" style="min-width: 35px;">Log</th>
<th class="sort-table" style="max-width: 35px;"><?=$lang['user']['active'];?></th>
<th style="text-align: right; min-width: 200px;" data-sortable="false"><?=$lang['user']['action'];?></th>
</tr>
</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)):
?>
<tr id="data">
<td><?=htmlspecialchars($row['host1'] . ':' . $row['port1']);?></td>
<td><?=htmlspecialchars($row['enc1']);?></td>
<td><?=htmlspecialchars($row['user1']);?></td>
- <td><?=($row['exclude'] == '') ? '&#10008;' : $row['exclude'];?></td>
+ <td><?=($row['exclude'] == '') ? '&#10008;' : '<code>' . $row['exclude'] . '</code>';?></td>
<td><?=htmlspecialchars($row['mins_interval']);?> min</td>
- <td><?=(empty($row['last_run'])) ? '&#10008;' : htmlspecialchars(date($lang['user']['syncjob_full_date'], strtotime($row['last_run'])));?></td>
+ <td><?=(empty($row['last_run'])) ? '&#10008;' : htmlspecialchars(date($lang['user']['syncjob_full_date'], strtotime($row['last_run'] . ' UTC')));?></td>
<td>
<?php
if (empty($row['returned_text'])) {
echo '&#10008;';
}
else {
?>
<a href="#logModal" data-toggle="modal" data-log-text="<?=htmlspecialchars($row['returned_text']);?>">Open logs</a>
<?php
}
?>
</td>
<td><?=($row['active'] == '1') ? '&#10004;' : '&#10008;';?></td>
<td style="text-align: right;">
<div class="btn-group">
<a href="/edit.php?syncjob=<?=urlencode($row['id']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['user']['edit'];?></a>
<a href="/delete.php?syncjob=<?=urlencode($row['id']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['user']['remove'];?></a>
</div>
</td>
</tr>
<?php
endwhile;
else:
?>
<tr id="no-data"><td colspan="9" style="text-align: center; font-style: italic;"><?=$lang['user']['no_record'];?></td></tr>
<?php
endif;
?>
</tbody>
<tfoot>
<tr id="no-data">
<td colspan="9" style="text-align: center; font-style: normal; border-top: 1px solid #e7e7e7;">
<a href="/add.php?syncjob"><?=$lang['user']['create_syncjob'];?></a>
</td>
</tr>
</tfoot>
</table>
</div>
+ </div>
</div>
</div>
<br />
<div class="modal fade" id="logModal" tabindex="-1" role="dialog" aria-labelledby="logTextLabel">
- <div class="modal-dialog modal-lg" role="document">
+ <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 -->
<script src="js/sorttable.js"></script>
<script src="js/user.js"></script>
<?php
require_once("inc/footer.inc.php");
} else {
header('Location: /');
exit();
}
?>

File Metadata

Mime Type
text/x-diff
Expires
9月 12 Fri, 3:12 AM (20 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5793
默认替代文本
(296 KB)

Event Timeline