[Web] Add multiple DKIM at once (+ button to auto-fill missing keys)
[Web] Duplicate DKIM keys from a single domain to a single or multiple domains [Web] WIP: Started Ratelimit rework [Web] Show RL in overview of mailbox and domains [Web] Move RL function out of mailbox functions file [Web] Some language fixes/changesmaster
parent
bbbdb13e6a
commit
d64a89473e
|
@ -208,6 +208,8 @@ $tfa_data = get_tfa();
|
|||
<?php
|
||||
foreach(mailbox('get', 'domains') as $domain) {
|
||||
if (!empty($dkim = dkim('details', $domain))) {
|
||||
$dkim_domains[] = $domain;
|
||||
($GLOBALS['SHOW_DKIM_PRIV_KEYS'] === true) ?: $dkim['privkey'] = base64_encode('Please set $SHOW_DKIM_PRIV_KEYS to true to show DKIM private keys.');
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-md-1"><input type="checkbox" data-id="dkim" name="multi_select" value="<?=$domain;?>" /></div>
|
||||
|
@ -229,7 +231,7 @@ $tfa_data = get_tfa();
|
|||
else {
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-md-1"><input type="checkbox" data-id="dkim" name="multi_select" value="<?=$domain;?>" disabled /></div>
|
||||
<div class="col-md-1"><input class="dkim_missing" type="checkbox" data-id="dkim" name="multi_select" value="<?=$domain;?>" disabled /></div>
|
||||
<div class="col-md-3">
|
||||
<p>Domain: <strong><?=htmlspecialchars($domain);?></strong><br /><span class="label label-danger"><?=$lang['admin']['dkim_key_missing'];?></span></p>
|
||||
</div>
|
||||
|
@ -240,6 +242,8 @@ $tfa_data = get_tfa();
|
|||
}
|
||||
foreach(mailbox('get', 'alias_domains', $domain) as $alias_domain) {
|
||||
if (!empty($dkim = dkim('details', $alias_domain))) {
|
||||
$dkim_domains[] = $alias_domain;
|
||||
($GLOBALS['SHOW_DKIM_PRIV_KEYS'] === true) ?: $dkim['privkey'] = base64_encode('Please set $SHOW_DKIM_PRIV_KEYS to true to show DKIM private keys.');
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-md-1"><input type="checkbox" data-id="dkim" name="multi_select" value="<?=$alias_domain;?>" /></div>
|
||||
|
@ -261,7 +265,7 @@ $tfa_data = get_tfa();
|
|||
else {
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-md-1"><input type="checkbox" data-id="dkim" name="multi_select" value="<?=$alias_domain;?>" disabled /></div>
|
||||
<div class="col-md-1"><input class="dkim_missing" type="checkbox" data-id="dkim" name="multi_select" value="<?=$alias_domain;?>" disabled /></div>
|
||||
<div class="col-md-2 col-md-offset-1">
|
||||
<p><small>↳ Alias-Domain: <strong><?=htmlspecialchars($alias_domain);?></strong><br /></small><span class="label label-danger"><?=$lang['admin']['dkim_key_missing'];?></span></p>
|
||||
</div>
|
||||
|
@ -274,6 +278,8 @@ $tfa_data = get_tfa();
|
|||
}
|
||||
foreach(dkim('blind') as $blind) {
|
||||
if (!empty($dkim = dkim('details', $blind))) {
|
||||
$dkim_domains[] = $blind;
|
||||
($GLOBALS['SHOW_DKIM_PRIV_KEYS'] === true) ?: $dkim['privkey'] = base64_encode('Please set $SHOW_DKIM_PRIV_KEYS to true to show DKIM private keys.');
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-md-1"><input type="checkbox" data-id="dkim" name="multi_select" value="<?=$blind;?>" /></div>
|
||||
|
@ -298,40 +304,90 @@ $tfa_data = get_tfa();
|
|||
<legend style="margin-top:40px"><?=$lang['admin']['dkim_add_key'];?></legend>
|
||||
<form class="form" data-id="dkim" role="form" method="post">
|
||||
<div class="form-group">
|
||||
<label for="domain">Domain</label>
|
||||
<input class="form-control" id="domain" name="domain" placeholder="example.org" required>
|
||||
<label for="domain"><?=$lang['admin']['domain_s'];?></label>
|
||||
<input class="form-control input-sm" id="dkim_add_domains" name="domains" placeholder="example.org, example.com" required>
|
||||
<small>↪ <a href="#" id="dkim_missing_keys"><?=$lang['admin']['dkim_domains_wo_keys'];?></a></small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="domain">Selector</label>
|
||||
<input class="form-control" id="dkim_selector" name="dkim_selector" value="dkim" required>
|
||||
<input class="form-control input-sm" id="dkim_selector" name="dkim_selector" value="dkim" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<select data-width="200px" class="form-control" id="key_size" name="key_size" title="<?=$lang['admin']['dkim_key_length'];?>" required>
|
||||
<select data-width="200px" data-style="btn btn-default btn-sm" class="form-control" id="key_size" name="key_size" title="<?=$lang['admin']['dkim_key_length'];?>" required>
|
||||
<option data-subtext="bits">1024</option>
|
||||
<option data-subtext="bits">2048</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-default" id="add_item" data-id="dkim" data-api-url='add/dkim' data-api-attr='{}' href="#"><span class="glyphicon glyphicon-plus"></span> <?=$lang['admin']['add'];?></button>
|
||||
<button class="btn btn-sm btn-default" id="add_item" data-id="dkim" data-api-url='add/dkim' data-api-attr='{}' href="#"><span class="glyphicon glyphicon-plus"></span> <?=$lang['admin']['add'];?></button>
|
||||
</form>
|
||||
|
||||
<legend data-target="#import_dkim" style="margin-top:40px;cursor:pointer" id="import_dkim_legend" unselectable="on" data-toggle="collapse"><span id="import_dkim_arrow" class="rotate glyphicon glyphicon-menu-down"></span> <?=$lang['admin']['import_private_key'];?></legend>
|
||||
<legend data-target="#import_dkim" style="margin-top:40px;cursor:pointer" id="import_dkim_legend" unselectable="on" data-toggle="collapse">
|
||||
<span id="import_dkim_arrow" style="font-size:12px" class="rotate glyphicon glyphicon-menu-down"></span> <?=$lang['admin']['import_private_key'];?>
|
||||
</legend>
|
||||
<div id="import_dkim" class="collapse">
|
||||
<form class="form" data-id="dkim_import" role="form" method="post">
|
||||
<div class="form-group">
|
||||
<label for="domain">Domain:</label>
|
||||
<input class="form-control" id="domain" name="domain" placeholder="example.org" required>
|
||||
<input class="form-control input-sm" id="domain" name="domain" placeholder="example.org" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="domain">Selector:</label>
|
||||
<input class="form-control" id="dkim_selector" name="dkim_selector" value="dkim" required>
|
||||
<input class="form-control input-sm" id="dkim_selector" name="dkim_selector" value="dkim" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="private_key_file"><?=$lang['admin']['private_key'];?>:</label>
|
||||
<textarea class="form-control" rows="5" name="private_key_file" id="private_key_file" required placeholder="-----BEGIN RSA KEY-----"></textarea>
|
||||
<textarea class="form-control input-sm" rows="10" name="private_key_file" id="private_key_file" required placeholder="-----BEGIN RSA KEY-----"></textarea>
|
||||
</div>
|
||||
<button class="btn btn-default" id="add_item" data-id="dkim_import" data-api-url='add/dkim_import' data-api-attr='{}' href="#"><span class="glyphicon glyphicon-plus"></span> <?=$lang['admin']['import'];?></button>
|
||||
<button class="btn btn-sm btn-default" id="add_item" data-id="dkim_import" data-api-url='add/dkim_import' data-api-attr='{}' href="#"><span class="glyphicon glyphicon-plus"></span> <?=$lang['admin']['import'];?></button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<legend data-target="#duplicate_dkim" style="margin-top:40px;cursor:pointer" id="duplicate_dkim_legend" unselectable="on" data-toggle="collapse">
|
||||
<span id="duplicate_dkim_arrow" style="font-size:12px" class="rotate glyphicon glyphicon-menu-down"></span> <?=$lang['admin']['duplicate_dkim'];?>
|
||||
</legend>
|
||||
<div id="duplicate_dkim" class="collapse">
|
||||
<form class="form-horizontal" data-id="dkim_duplicate" role="form" method="post">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="from_domain"><?=$lang['admin']['dkim_from'];?>:</label>
|
||||
<div class="col-sm-10">
|
||||
<select data-style="btn btn-default btn-sm"
|
||||
data-live-search="true"
|
||||
data-id="dkim_duplicate"
|
||||
title="<?=$lang['admin']['dkim_from_title'];?>"
|
||||
name="from_domain" id="from_domain" class="full-width-select form-control" required>
|
||||
<?php
|
||||
foreach ($dkim_domains as $dkim) {
|
||||
?>
|
||||
<option value="<?=$dkim;?>"><?=$dkim;?></option>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="to_domain"><?=$lang['admin']['dkim_to'];?>:</label>
|
||||
<div class="col-sm-10">
|
||||
<select
|
||||
data-live-search="true"
|
||||
data-style="btn btn-default btn-sm"
|
||||
data-id="dkim_duplicate"
|
||||
title="<?=$lang['admin']['dkim_to_title'];?>"
|
||||
name="to_domain" id="to_domain" class="full-width-select form-control" multiple required>
|
||||
<?php
|
||||
foreach (array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains')) as $domain) {
|
||||
?>
|
||||
<option value="<?=$domain;?>"><?=$domain;?></option>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-default" id="add_item" data-id="dkim_duplicate" data-api-url='add/dkim_duplicate' data-api-attr='{}' href="#"><span class="glyphicon glyphicon-duplicate"></span> <?=$lang['admin']['duplicate'];?></button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -71,3 +71,6 @@ body.modal-open {
|
|||
.table-condensed .input-sm {
|
||||
width: 100%!important;
|
||||
}
|
||||
.full-width-select {
|
||||
width: 100%!important;
|
||||
}
|
||||
|
|
|
@ -101,6 +101,7 @@ legend {
|
|||
-ms-user-select: none
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
font-size: 12pt;
|
||||
}
|
||||
.navbar .navbar-brand {
|
||||
padding-top: 5px;
|
||||
|
|
|
@ -153,7 +153,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
!empty($_GET["domain"])) {
|
||||
$domain = $_GET["domain"];
|
||||
$result = mailbox('get', 'domain_details', $domain);
|
||||
$rl = mailbox('get', 'ratelimit', $domain);
|
||||
$rl = ratelimit('get', 'domain', $domain);
|
||||
$rlyhosts = relayhost('get');
|
||||
if (!empty($result)) {
|
||||
?>
|
||||
|
@ -266,7 +266,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button class="btn btn-default" id="edit_selected" data-id="domratelimit" data-item="<?=$domain;?>" data-api-url='edit/ratelimit' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
|
||||
<button class="btn btn-default" id="edit_selected" data-id="domratelimit" data-item="<?=$domain;?>" data-api-url='edit/rl-domain' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
|
||||
</div>
|
||||
</form>
|
||||
<hr>
|
||||
|
@ -329,7 +329,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
!empty($_GET["aliasdomain"])) {
|
||||
$alias_domain = html_entity_decode(rawurldecode($_GET["aliasdomain"]));
|
||||
$result = mailbox('get', 'alias_domain_details', $alias_domain);
|
||||
$rl = mailbox('get', 'ratelimit', $alias_domain);
|
||||
$rl = ratelimit('get', 'domain', $alias_domain);
|
||||
if (!empty($result)) {
|
||||
?>
|
||||
<h4><?=$lang['edit']['edit_alias_domain'];?></h4>
|
||||
|
@ -368,7 +368,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button class="btn btn-default" id="edit_selected" data-id="domratelimit" data-item="<?=$alias_domain;?>" data-api-url='edit/ratelimit' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
|
||||
<button class="btn btn-default" id="edit_selected" data-id="domratelimit" data-item="<?=$alias_domain;?>" data-api-url='edit/rl-domain' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
|
@ -395,7 +395,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
elseif (isset($_GET['mailbox']) && filter_var(html_entity_decode(rawurldecode($_GET["mailbox"])), FILTER_VALIDATE_EMAIL) && !empty($_GET["mailbox"])) {
|
||||
$mailbox = html_entity_decode(rawurldecode($_GET["mailbox"]));
|
||||
$result = mailbox('get', 'mailbox_details', $mailbox);
|
||||
$rl = mailbox('get', 'ratelimit', $mailbox);
|
||||
$rl = ratelimit('get', 'mailbox', $mailbox);
|
||||
if (!empty($result)) {
|
||||
?>
|
||||
<h4><?=$lang['edit']['mailbox'];?></h4>
|
||||
|
@ -522,7 +522,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button class="btn btn-default" id="edit_selected" data-id="mboxratelimit" data-item="<?=htmlspecialchars($mailbox);?>" data-api-url='edit/ratelimit' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
|
||||
<button class="btn btn-default" id="edit_selected" data-id="mboxratelimit" data-item="<?=htmlspecialchars($mailbox);?>" data-api-url='edit/rl-mbox' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="446.22601"
|
||||
height="396.02499"
|
||||
viewBox="0 0 446.226 396.02499"
|
||||
width="374.82101"
|
||||
height="356.871"
|
||||
viewBox="0 0 374.821 356.871"
|
||||
enable-background="new 0 0 1600 1200"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
|
@ -36,19 +36,19 @@
|
|||
inkscape:window-height="1138"
|
||||
id="namedview140"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.1125147"
|
||||
inkscape:cx="261.00704"
|
||||
inkscape:cy="233.97883"
|
||||
inkscape:zoom="1.5733334"
|
||||
inkscape:cx="264.82839"
|
||||
inkscape:cy="340.43592"
|
||||
inkscape:window-x="814"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="Layer_1"
|
||||
inkscape:current-layer="g3"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" /><g
|
||||
id="g3"
|
||||
transform="translate(-576.88698,-401.988)"><g
|
||||
transform="translate(-648.292,-401.988)"><g
|
||||
id="g5"><g
|
||||
id="g7"><g
|
||||
id="email"><path
|
||||
|
@ -59,7 +59,7 @@
|
|||
d="M 758.871,656.221 649.49,747.45 c 2.507,6.648 8.901,11.409 16.44,11.409 l 235.998,0 c 7.536,0 13.933,-4.761 16.444,-11.409 l -107.402,-91.229 -52.099,0 z"
|
||||
id="path12"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#fee70f;fill-opacity:0.89499998" /><g
|
||||
style="fill:#fee70f;fill-opacity:0.89499996" /><g
|
||||
id="g14"><path
|
||||
d="m 810.391,656.686 107.981,90.764 c -0.331,0.881 -0.744,1.726 -1.205,2.536 l 0.028,0.035 c 1.501,-2.596 2.371,-5.594 2.371,-8.81 l 0,-172.004 -109.175,87.479 z"
|
||||
id="path16"
|
||||
|
@ -76,13 +76,7 @@
|
|||
d="m 984.594,658.413 c 3.59,-9.156 7.701,-11 9.346,-11.346 -49.276,4.542 -32.99,38.693 -32.99,38.693 0,0 6.229,14.728 26.532,13.892 27.063,0.461 35.631,-50.166 35.631,-50.166 -6.654,11.655 -26.404,9.876 -38.519,8.927 z"
|
||||
id="path22"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#fef3df" /><ellipse
|
||||
cx="787.75098"
|
||||
cy="788.54498"
|
||||
rx="210.864"
|
||||
ry="9.4680004"
|
||||
id="ellipse24"
|
||||
style="fill:#f1f2f2" /><path
|
||||
style="fill:#fef3df" /><path
|
||||
d="m 783.931,446.247 c -66.396,0 -120.223,53.827 -120.223,120.223 0,66.396 53.827,120.221 120.223,120.221 66.397,0 120.222,-53.825 120.222,-120.221 0,-66.395 -53.825,-120.223 -120.222,-120.223 z m -11.96,215.702 c -53.009,0 -95.982,-43.855 -95.982,-97.953 0,-54.098 42.973,-97.952 95.982,-97.952 53.007,0 95.98,43.855 95.98,97.952 -10e-4,54.098 -42.973,97.953 -95.98,97.953 z"
|
||||
id="path26"
|
||||
inkscape:connector-curvature="0"
|
||||
|
@ -138,10 +132,11 @@
|
|||
inkscape:connector-curvature="0"
|
||||
style="fill:#5a3620" /></g></g></g><g
|
||||
id="g72"><path
|
||||
d="m 875.228,525.835 c 0.354,-3.113 0.634,-6.311 0.743,-9.754 0.035,-1.218 0.109,-2.384 0.109,-3.661 0,-40.785 -33.369,-74.043 -80.237,-75.775 l -7.335,0.005 c -0.003,0 -0.003,0 -0.006,0 -0.007,0.018 -28.632,88.422 76.583,140.268 0.946,-4.317 2.078,-9.585 2.73,-13.088 2.64,-14.196 5.934,-25.021 7.413,-37.995 z"
|
||||
d="m 875.228,525.835 c 0.354,-3.113 0.634,-6.311 0.743,-9.754 0.035,-1.218 0.109,-2.384 0.109,-3.661 0,-40.785 -33.369,-74.043 -80.237,-75.775 l -7.335,0.005 -0.006,0 c -0.007,0.018 -25.93541,90.33209 79.27959,142.17809 3.15658,-17.35082 5.65276,-38.01947 7.44641,-52.99309 z"
|
||||
id="path74"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#87654a" /></g><g
|
||||
style="fill:#87654a"
|
||||
sodipodi:nodetypes="ccsccccc" /></g><g
|
||||
id="g76"><g
|
||||
id="g78"><g
|
||||
id="g80"><g
|
||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
@ -15,61 +15,49 @@ function dkim($_action, $_data = null) {
|
|||
}
|
||||
$key_length = intval($_data['key_size']);
|
||||
$dkim_selector = (isset($_data['dkim_selector'])) ? $_data['dkim_selector'] : 'dkim';
|
||||
$domain = $_data['domain'];
|
||||
if (!is_valid_domain_name($domain) || !is_numeric($key_length)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => 'dkim_domain_or_sel_invalid'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if ($redis->hGet('DKIM_PUB_KEYS', $domain)) {
|
||||
$domains = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['domains']));
|
||||
$domains = array_filter($domains);
|
||||
foreach ($domains as $domain) {
|
||||
if (!is_valid_domain_name($domain) || !is_numeric($key_length)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => 'dkim_domain_or_sel_invalid'
|
||||
'msg' => array('dkim_domain_or_sel_invalid', $domain)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (!ctype_alnum($dkim_selector)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => 'dkim_domain_or_sel_invalid'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$config = array(
|
||||
"digest_alg" => "sha256",
|
||||
"private_key_bits" => $key_length,
|
||||
"private_key_type" => OPENSSL_KEYTYPE_RSA,
|
||||
);
|
||||
if ($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 and selector to redis
|
||||
try {
|
||||
$redis->hSet('DKIM_PUB_KEYS', $domain, $pubKey);
|
||||
$redis->hSet('DKIM_SELECTORS', $domain, $dkim_selector);
|
||||
continue;
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
if ($redis->hGet('DKIM_PUB_KEYS', $domain)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => array('redis_error', $e)
|
||||
'msg' => array('dkim_domain_or_sel_invalid', $domain)
|
||||
);
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
// Export private key and save private key to redis
|
||||
openssl_pkey_export($keypair_ressource, $privKey);
|
||||
if (isset($privKey) && !empty($privKey)) {
|
||||
if (!ctype_alnum($dkim_selector)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => array('dkim_domain_or_sel_invalid', $domain)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
$config = array(
|
||||
"digest_alg" => "sha256",
|
||||
"private_key_bits" => $key_length,
|
||||
"private_key_type" => OPENSSL_KEYTYPE_RSA,
|
||||
);
|
||||
if ($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 and selector to redis
|
||||
try {
|
||||
$redis->hSet('DKIM_PRIV_KEYS', $dkim_selector . '.' . $domain, trim($privKey));
|
||||
$redis->hSet('DKIM_PUB_KEYS', $domain, $pubKey);
|
||||
$redis->hSet('DKIM_SELECTORS', $domain, $dkim_selector);
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
|
@ -77,23 +65,79 @@ function dkim($_action, $_data = null) {
|
|||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
// Export private key and save private key to redis
|
||||
openssl_pkey_export($keypair_ressource, $privKey);
|
||||
if (isset($privKey) && !empty($privKey)) {
|
||||
try {
|
||||
$redis->hSet('DKIM_PRIV_KEYS', $dkim_selector . '.' . $domain, trim($privKey));
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => array('dkim_added', $domain)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => array('dkim_domain_or_sel_invalid', $domain)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'duplicate':
|
||||
if ($_SESSION['mailcow_cc_role'] != "admin") {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$from_domain = $_data['from_domain'];
|
||||
$from_domain_dkim = dkim('details', $from_domain);
|
||||
if (empty($from_domain_dkim)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => array('dkim_domain_or_sel_invalid', $from_domain)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
$to_domains = (array)$_data['to_domain'];
|
||||
$to_domains = array_filter($to_domains);
|
||||
foreach ($to_domains as $to_domain) {
|
||||
try {
|
||||
$redis->hSet('DKIM_PUB_KEYS', $to_domain, $from_domain_dkim['pubkey']);
|
||||
$redis->hSet('DKIM_SELECTORS', $to_domain, $from_domain_dkim['dkim_selector']);
|
||||
$redis->hSet('DKIM_PRIV_KEYS', $from_domain_dkim['dkim_selector'] . '.' . $to_domain, trim($from_domain_dkim['privkey']));
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => 'dkim_added'
|
||||
'msg' => array('dkim_duplicated', $from_domain, $to_domain)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => 'dkim_domain_or_sel_invalid'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'import':
|
||||
|
@ -129,7 +173,7 @@ function dkim($_action, $_data = null) {
|
|||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => 'dkim_domain_or_sel_invalid'
|
||||
'msg' => array('dkim_domain_or_sel_invalid', $domain)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
@ -137,7 +181,7 @@ function dkim($_action, $_data = null) {
|
|||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => 'dkim_domain_or_sel_invalid'
|
||||
'msg' => array('dkim_domain_or_sel_invalid', $domain)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
@ -145,7 +189,7 @@ function dkim($_action, $_data = null) {
|
|||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => 'dkim_domain_or_sel_invalid'
|
||||
'msg' => array('dkim_domain_or_sel_invalid', $domain)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
@ -178,7 +222,7 @@ function dkim($_action, $_data = null) {
|
|||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_data),
|
||||
'msg' => 'dkim_added'
|
||||
'msg' => array('dkim_added', $domain)
|
||||
);
|
||||
return true;
|
||||
break;
|
||||
|
@ -203,13 +247,7 @@ function dkim($_action, $_data = null) {
|
|||
}
|
||||
$dkimdata['dkim_txt'] = 'v=DKIM1;k=rsa;t=s;s=email;p=' . $redis_dkim_key_data;
|
||||
$dkimdata['dkim_selector'] = $redis->hGet('DKIM_SELECTORS', $_data);
|
||||
$dkimdata['privkey'] = $redis->hGet('DKIM_PRIV_KEYS', $dkimdata['dkim_selector'] . $_data);
|
||||
if ($GLOBALS['SHOW_DKIM_PRIV_KEYS'] === true) {
|
||||
$dkimdata['privkey'] = base64_encode($redis->hGet('DKIM_PRIV_KEYS', $dkimdata['dkim_selector'] . '.' . $_data));
|
||||
}
|
||||
else {
|
||||
$dkimdata['privkey'] = base64_encode('Please set $SHOW_DKIM_PRIV_KEYS to true to show DKIM private keys.');
|
||||
}
|
||||
$dkimdata['privkey'] = base64_encode($redis->hGet('DKIM_PRIV_KEYS', $dkimdata['dkim_selector'] . '.' . $_data));
|
||||
}
|
||||
return $dkimdata;
|
||||
break;
|
||||
|
|
|
@ -1291,86 +1291,6 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||
);
|
||||
}
|
||||
break;
|
||||
case 'ratelimit':
|
||||
if (!is_array($_data['object'])) {
|
||||
$objects = array();
|
||||
$objects[] = $_data['object'];
|
||||
}
|
||||
else {
|
||||
$objects = $_data['object'];
|
||||
}
|
||||
foreach ($objects as $object) {
|
||||
$rl_value = intval($_data['rl_value']);
|
||||
$rl_frame = $_data['rl_frame'];
|
||||
if (!in_array($rl_frame, array('s', 'm', 'h'))) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => 'rl_timeframe'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (is_valid_domain_name($object)) {
|
||||
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
elseif (filter_var($object, FILTER_VALIDATE_EMAIL)) {
|
||||
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (empty($rl_value)) {
|
||||
try {
|
||||
$redis->hDel('RL_VALUE', $object);
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$redis->hSet('RL_VALUE', $object, $rl_value . ' / 1' . $rl_frame);
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => array('object_modified', $object)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'syncjob':
|
||||
if (!is_array($_data['id'])) {
|
||||
$ids = array();
|
||||
|
@ -2670,51 +2590,6 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||
}
|
||||
return $aliases;
|
||||
break;
|
||||
case 'ratelimit':
|
||||
if (is_valid_domain_name($_data)) {
|
||||
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
elseif (filter_var($_data, FILTER_VALIDATE_EMAIL)) {
|
||||
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if ($rl_value = $redis->hGet('RL_VALUE', $_data)) {
|
||||
$rl = explode(' / 1', $rl_value);
|
||||
$data['value'] = $rl[0];
|
||||
$data['frame'] = $rl[1];
|
||||
return $data;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case 'alias_details':
|
||||
$aliasdata = array();
|
||||
$stmt = $pdo->prepare("SELECT
|
||||
|
@ -2759,6 +2634,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||
break;
|
||||
case 'alias_domain_details':
|
||||
$aliasdomaindata = array();
|
||||
$rl = ratelimit('get', 'domain', $_data);
|
||||
$stmt = $pdo->prepare("SELECT
|
||||
`alias_domain`,
|
||||
`target_domain`,
|
||||
|
@ -2775,6 +2651,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||
$aliasdomaindata['alias_domain'] = $row['alias_domain'];
|
||||
$aliasdomaindata['target_domain'] = $row['target_domain'];
|
||||
$aliasdomaindata['active'] = $row['active'];
|
||||
$aliasdomaindata['rl'] = $rl;
|
||||
$aliasdomaindata['active_int'] = $row['active_int'];
|
||||
$aliasdomaindata['created'] = $row['created'];
|
||||
$aliasdomaindata['modified'] = $row['modified'];
|
||||
|
@ -2848,6 +2725,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||
AND `domain` = :domain");
|
||||
$stmt->execute(array(':domain' => $row['domain']));
|
||||
$MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$rl = ratelimit('get', 'domain', $_data);
|
||||
$domaindata['max_new_mailbox_quota'] = ($row['quota'] * 1048576) - $MailboxDataDomain['in_use'];
|
||||
if ($domaindata['max_new_mailbox_quota'] > ($row['maxquota'] * 1048576)) {
|
||||
$domaindata['max_new_mailbox_quota'] = ($row['maxquota'] * 1048576);
|
||||
|
@ -2864,6 +2742,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||
$domaindata['relayhost'] = $row['relayhost'];
|
||||
$domaindata['backupmx'] = $row['backupmx'];
|
||||
$domaindata['backupmx_int'] = $row['backupmx_int'];
|
||||
$domaindata['rl'] = $rl;
|
||||
$domaindata['active'] = $row['active'];
|
||||
$domaindata['active_int'] = $row['active_int'];
|
||||
$domaindata['relay_all_recipients'] = $row['relay_all_recipients'];
|
||||
|
@ -2887,6 +2766,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||
return false;
|
||||
}
|
||||
$mailboxdata = array();
|
||||
$rl = ratelimit('get', 'mailbox', $_data);
|
||||
$stmt = $pdo->prepare("SELECT
|
||||
`domain`.`backupmx`,
|
||||
`mailbox`.`username`,
|
||||
|
@ -2918,6 +2798,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||
$mailboxdata['max_new_quota'] = ($DomainQuota['maxquota'] * 1048576);
|
||||
}
|
||||
$mailboxdata['username'] = $row['username'];
|
||||
$mailboxdata['rl'] = $rl;
|
||||
$mailboxdata['is_relayed'] = $row['backupmx'];
|
||||
$mailboxdata['name'] = $row['name'];
|
||||
$mailboxdata['active'] = $row['active'];
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
function ratelimit($_action, $_scope, $_data = null) {
|
||||
global $redis;
|
||||
global $lang;
|
||||
$_data_log = $_data;
|
||||
switch ($_action) {
|
||||
case 'edit':
|
||||
switch ($_scope) {
|
||||
case 'domain':
|
||||
if (!is_array($_data['object'])) {
|
||||
$objects = array();
|
||||
$objects[] = $_data['object'];
|
||||
}
|
||||
else {
|
||||
$objects = $_data['object'];
|
||||
}
|
||||
foreach ($objects as $object) {
|
||||
$rl_value = intval($_data['rl_value']);
|
||||
$rl_frame = $_data['rl_frame'];
|
||||
if (!in_array($rl_frame, array('s', 'm', 'h'))) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => 'rl_timeframe'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (empty($rl_value)) {
|
||||
try {
|
||||
$redis->hDel('RL_VALUE', $object);
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$redis->hSet('RL_VALUE', $object, $rl_value . ' / 1' . $rl_frame);
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => array('object_modified', $object)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'mailbox':
|
||||
if (!is_array($_data['object'])) {
|
||||
$objects = array();
|
||||
$objects[] = $_data['object'];
|
||||
}
|
||||
else {
|
||||
$objects = $_data['object'];
|
||||
}
|
||||
foreach ($objects as $object) {
|
||||
$rl_value = intval($_data['rl_value']);
|
||||
$rl_frame = $_data['rl_frame'];
|
||||
if (!in_array($rl_frame, array('s', 'm', 'h'))) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => 'rl_timeframe'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $object)
|
||||
|| ($_SESSION['mailcow_cc_role'] != 'admin' && $_SESSION['mailcow_cc_role'] != 'domainadmin')) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (empty($rl_value)) {
|
||||
try {
|
||||
$redis->hDel('RL_VALUE', $object);
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$redis->hSet('RL_VALUE', $object, $rl_value . ' / 1' . $rl_frame);
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => array('object_modified', $object)
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'get':
|
||||
switch ($_scope) {
|
||||
case 'domain':
|
||||
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if ($rl_value = $redis->hGet('RL_VALUE', $_data)) {
|
||||
$rl = explode(' / 1', $rl_value);
|
||||
$data['value'] = $rl[0];
|
||||
$data['frame'] = $rl[1];
|
||||
return $data;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case 'mailbox':
|
||||
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)
|
||||
|| ($_SESSION['mailcow_cc_role'] != 'admin' && $_SESSION['mailcow_cc_role'] != 'domainadmin')) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if ($rl_value = $redis->hGet('RL_VALUE', $_data)) {
|
||||
$rl = explode(' / 1', $rl_value);
|
||||
$data['value'] = $rl[0];
|
||||
$data['frame'] = $rl[1];
|
||||
return $data;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (RedisException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => array('redis_error', $e)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -132,6 +132,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.quarantine.inc.php';
|
|||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.policy.inc.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.dkim.inc.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.fwdhost.inc.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.ratelimit.inc.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.relayhost.inc.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.rsettings.inc.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.fail2ban.inc.php';
|
||||
|
|
|
@ -9,6 +9,10 @@ jQuery(function($){
|
|||
e.preventDefault();
|
||||
$('#import_dkim_arrow').toggleClass("animation");
|
||||
});
|
||||
$("#duplicate_dkim_legend").on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$('#duplicate_dkim_arrow').toggleClass("animation");
|
||||
});
|
||||
$("#rspamd_preset_1").on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$("form[data-id=rsetting]").find("#desc").val(lang.rsettings_preset_1);
|
||||
|
@ -19,6 +23,14 @@ jQuery(function($){
|
|||
$("form[data-id=rsetting]").find("#desc").val(lang.rsettings_preset_2);
|
||||
$("form[data-id=rsetting]").find("#content").val('priority = 10;\nrcpt = "/postmaster@.*/";\nwant_spam = yes;');
|
||||
});
|
||||
$("#dkim_missing_keys").on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var domains = [];
|
||||
$('.dkim_missing').each(function() {
|
||||
domains.push($(this).val());
|
||||
});
|
||||
$('#dkim_add_domains').val(domains);
|
||||
});
|
||||
function draw_domain_admins() {
|
||||
ft_domainadmins = FooTable.init('#domainadminstable', {
|
||||
"columns": [
|
||||
|
|
|
@ -171,7 +171,7 @@ jQuery(function($){
|
|||
{"name":"user","title":"User"},
|
||||
{"name":"role","title":"Role"},
|
||||
{"name":"remote","title":"IP"},
|
||||
{"name":"msg","title":lang.message},
|
||||
{"name":"msg","title":lang.message,"style":{"word-break":"break-all"}},
|
||||
{"name":"call","title":"Call","breakpoints": "all"},
|
||||
],
|
||||
"rows": $.ajax({
|
||||
|
|
|
@ -264,6 +264,7 @@ jQuery(function($){
|
|||
},
|
||||
},
|
||||
{"name":"max_quota_for_mbox","title":lang.mailbox_quota,"breakpoints":"xs sm","style":{"width":"125px"}},
|
||||
{"name":"rl","title":"RL","breakpoints":"xs sm md","style":{"width":"125px"}},
|
||||
{"name":"backupmx","filterable": false,"style":{"maxWidth":"120px","width":"120px"},"title":lang.backup_mx,"breakpoints":"xs sm"},
|
||||
{"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"240px","width":"240px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
|
||||
|
@ -280,6 +281,13 @@ jQuery(function($){
|
|||
item.aliases = item.aliases_in_domain + " / " + item.max_num_aliases_for_domain;
|
||||
item.mailboxes = item.mboxes_in_domain + " / " + item.max_num_mboxes_for_domain;
|
||||
item.quota = item.quota_used_in_domain + "/" + item.max_quota_for_domain;
|
||||
if (!item.rl) {
|
||||
item.rl = '∞';
|
||||
} else {
|
||||
item.rl = $.map(item.rl, function(e){
|
||||
return e;
|
||||
}).join('/1');
|
||||
}
|
||||
item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
|
||||
item.chkbox = '<input type="checkbox" data-id="domain" name="multi_select" value="' + encodeURIComponent(item.domain_name) + '" />';
|
||||
item.action = '<div class="btn-group">';
|
||||
|
@ -342,6 +350,7 @@ jQuery(function($){
|
|||
},
|
||||
},
|
||||
{"name":"messages","filterable": false,"title":lang.msg_num,"breakpoints":"xs sm md"},
|
||||
{"name":"rl","title":"RL","breakpoints":"xs sm md","style":{"width":"125px"}},
|
||||
{"name":"active","filterable": false,"title":lang.active},
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"min-width":"250px","text-align":"right"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
|
||||
],
|
||||
|
@ -357,6 +366,13 @@ jQuery(function($){
|
|||
$.each(data, function (i, item) {
|
||||
item.quota = item.quota_used + "/" + item.quota;
|
||||
item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
|
||||
if (!item.rl) {
|
||||
item.rl = '∞';
|
||||
} else {
|
||||
item.rl = $.map(item.rl, function(e){
|
||||
return e;
|
||||
}).join('/1');
|
||||
}
|
||||
item.chkbox = '<input type="checkbox" data-id="mailbox" name="multi_select" value="' + encodeURIComponent(item.username) + '" />';
|
||||
if (role == "admin") {
|
||||
item.action = '<div class="btn-group">' +
|
||||
|
|
|
@ -135,6 +135,9 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
|
|||
case "dkim":
|
||||
process_add_return(dkim('add', $attr));
|
||||
break;
|
||||
case "dkim_duplicate":
|
||||
process_add_return(dkim('duplicate', $attr));
|
||||
break;
|
||||
case "dkim_import":
|
||||
process_add_return(dkim('import', $attr));
|
||||
break;
|
||||
|
@ -181,6 +184,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
|
|||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case "domain":
|
||||
switch ($object) {
|
||||
case "all":
|
||||
|
@ -208,6 +212,67 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
|
|||
}
|
||||
break;
|
||||
|
||||
case "rl-domain":
|
||||
switch ($object) {
|
||||
case "all":
|
||||
$domains = array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains'));
|
||||
if (!empty($domains)) {
|
||||
foreach ($domains as $domain) {
|
||||
if ($details = ratelimit('get', 'domain', $domain)) {
|
||||
$details['domain'] = $domain;
|
||||
$data[] = $details;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
process_get_return($data);
|
||||
}
|
||||
else {
|
||||
echo '{}';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$data = ratelimit('get', 'domain', $object);
|
||||
process_get_return($data);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case "rl-mbox":
|
||||
switch ($object) {
|
||||
case "all":
|
||||
$domains = mailbox('get', 'domains');
|
||||
if (!empty($domains)) {
|
||||
foreach ($domains as $domain) {
|
||||
$mailboxes = mailbox('get', 'mailboxes', $domain);
|
||||
if (!empty($mailboxes)) {
|
||||
foreach ($mailboxes as $mailbox) {
|
||||
if ($details = ratelimit('get', 'mailbox', $mailbox)) {
|
||||
$details['mailbox'] = $mailbox;
|
||||
$data[] = $details;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
process_get_return($data);
|
||||
}
|
||||
else {
|
||||
echo '{}';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$data = ratelimit('get', 'mailbox', $object);
|
||||
process_get_return($data);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case "relayhost":
|
||||
switch ($object) {
|
||||
case "all":
|
||||
|
@ -968,8 +1033,11 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
|
|||
case "domain":
|
||||
process_edit_return(mailbox('edit', 'domain', array_merge(array('domain' => $items), $attr)));
|
||||
break;
|
||||
case "ratelimit":
|
||||
process_edit_return(mailbox('edit', 'ratelimit', array_merge(array('object' => $items), $attr)));
|
||||
case "rl-domain":
|
||||
process_edit_return(ratelimit('edit', 'domain', array_merge(array('object' => $items), $attr)));
|
||||
break;
|
||||
case "rl-mbox":
|
||||
process_edit_return(ratelimit('edit', 'mailbox', array_merge(array('object' => $items), $attr)));
|
||||
break;
|
||||
case "alias-domain":
|
||||
process_edit_return(mailbox('edit', 'alias_domain', array_merge(array('alias_domain' => $items), $attr)));
|
||||
|
|
|
@ -65,6 +65,7 @@ $lang['success']['saved_settings'] = "Regel wurde gespeichert";
|
|||
$lang['danger']['dkim_domain_or_sel_invalid'] = 'DKIM-Domain oder Selektor nicht korrekt: %s';
|
||||
$lang['success']['dkim_removed'] = 'DKIM-Key wurde entfernt';
|
||||
$lang['success']['dkim_added'] = 'DKIM-Key wurde hinzugefügt';
|
||||
$lang['success']['dkim_duplicated'] = "DKIM-Key der Domain %s wurde auf Domain %s kopiert";
|
||||
$lang['danger']['access_denied'] = 'Zugriff verweigert oder unvollständige/ungültige Daten';
|
||||
$lang['danger']['domain_invalid'] = 'Domainname %s ist ungültig';
|
||||
$lang['danger']['mailbox_quota_exceeds_domain_quota'] = 'Maximale Größe für Mailboxen überschreitet das Domain Speicherlimit';
|
||||
|
@ -249,6 +250,7 @@ $lang['mailbox']['kind'] = 'Art';
|
|||
$lang['mailbox']['description'] = 'Beschreibung';
|
||||
$lang['mailbox']['resources'] = 'Ressourcen';
|
||||
$lang['mailbox']['domains'] = 'Domains';
|
||||
$lang['admin']['domain_s'] = 'Domain(s)';
|
||||
$lang['mailbox']['mailboxes'] = 'Mailboxen';
|
||||
$lang['mailbox']['mailbox_quota'] = 'Max. Größe einer Mailbox';
|
||||
$lang['mailbox']['domain_quota'] = 'Gesamtspeicher';
|
||||
|
@ -436,7 +438,9 @@ $lang['admin']['no_new_rows'] = 'Keine weiteren Zeilen vorhanden';
|
|||
$lang['admin']['additional_rows'] = ' zusätzliche Zeilen geladen'; // parses to 'n additional rows were added'
|
||||
$lang['admin']['private_key'] = 'Private Key';
|
||||
$lang['admin']['import'] = 'Importieren';
|
||||
$lang['admin']['duplicate'] = 'Duplizieren';
|
||||
$lang['admin']['import_private_key'] = 'Private Key importieren';
|
||||
$lang['admin']['duplicate_dkim'] = 'DKIM duplizieren';
|
||||
$lang['admin']['f2b_parameters'] = 'Fail2ban Parameter';
|
||||
$lang['admin']['f2b_ban_time'] = 'Banzeit (s)';
|
||||
$lang['admin']['f2b_max_attempts'] = 'Max. Versuche';
|
||||
|
@ -453,6 +457,11 @@ $lang['admin']['dkim_keys'] = 'ARC/DKIM-Keys';
|
|||
$lang['admin']['dkim_key_valid'] = 'Key gültig';
|
||||
$lang['admin']['dkim_key_unused'] = 'Key ohne Zuweisung';
|
||||
$lang['admin']['dkim_key_missing'] = 'Key fehlt';
|
||||
$lang['admin']['dkim_from'] = 'Von';
|
||||
$lang['admin']['dkim_to'] = 'Nach';
|
||||
$lang['admin']['dkim_from_title'] = 'Quellobjekt für Duplizierung';
|
||||
$lang['admin']['dkim_to_title'] = 'Ziel-Objekt(e) werden überschrieben';
|
||||
$lang['admin']['dkim_domains_wo_keys'] = "Domains mit fehlenden Keys auswählen";
|
||||
$lang['admin']['add'] = 'Hinzufügen';
|
||||
$lang['add']['add_domain_restart'] = 'Domain hinzufügen und SOGo neustarten';
|
||||
$lang['add']['add_domain_only'] = 'Nur Domain hinzufügen';
|
||||
|
|
|
@ -68,7 +68,8 @@ $lang['warning']['session_token'] = "Form token invalid: Token mismatch";
|
|||
|
||||
$lang['danger']['dkim_domain_or_sel_invalid'] = "DKIM domain or selector invalid: %s";
|
||||
$lang['success']['dkim_removed'] = "DKIM key %s has been removed";
|
||||
$lang['success']['dkim_added'] = "DKIM key has been saved";
|
||||
$lang['success']['dkim_added'] = "DKIM key %s has been saved";
|
||||
$lang['success']['dkim_duplicated'] = "DKIM key for domain %s has been copied to %s";
|
||||
$lang['danger']['access_denied'] = "Access denied or invalid form data";
|
||||
$lang['danger']['domain_invalid'] = "Domain name %s is invalid";
|
||||
$lang['danger']['mailbox_quota_exceeds_domain_quota'] = "Max. quota exceeds domain quota limit";
|
||||
|
@ -250,6 +251,7 @@ $lang['mailbox']['description'] = 'Description';
|
|||
$lang['mailbox']['alias'] = 'Alias';
|
||||
$lang['mailbox']['aliases'] = 'Aliases';
|
||||
$lang['mailbox']['domains'] = 'Domains';
|
||||
$lang['admin']['domain_s'] = 'Domain/s';
|
||||
$lang['mailbox']['mailboxes'] = 'Mailboxes';
|
||||
$lang['mailbox']['resources'] = 'Resources';
|
||||
$lang['mailbox']['mailbox_quota'] = 'Max. size of a mailbox';
|
||||
|
@ -445,7 +447,13 @@ $lang['admin']['no_new_rows'] = 'No further rows available';
|
|||
$lang['admin']['additional_rows'] = ' additional rows were added'; // parses to 'n additional rows were added'
|
||||
$lang['admin']['private_key'] = 'Private key';
|
||||
$lang['admin']['import'] = 'Import';
|
||||
$lang['admin']['duplicate'] = 'Duplicate';
|
||||
$lang['admin']['import_private_key'] = 'Import private key';
|
||||
$lang['admin']['duplicate_dkim'] = 'Duplicate DKIM record';
|
||||
$lang['admin']['dkim_from'] = 'From';
|
||||
$lang['admin']['dkim_to'] = 'To';
|
||||
$lang['admin']['dkim_from_title'] = 'Source domain to copy data from';
|
||||
$lang['admin']['dkim_to_title'] = 'Target domain/s - will be overwritten';
|
||||
$lang['admin']['f2b_parameters'] = 'Fail2ban parameters';
|
||||
$lang['admin']['f2b_ban_time'] = 'Ban time (s)';
|
||||
$lang['admin']['f2b_max_attempts'] = 'Max. attempts';
|
||||
|
@ -465,6 +473,7 @@ $lang['admin']['dkim_key_unused'] = 'Key unused';
|
|||
$lang['admin']['dkim_key_missing'] = 'Key missing';
|
||||
$lang['admin']['dkim_add_key'] = 'Add ARC/DKIM key';
|
||||
$lang['admin']['dkim_keys'] = 'ARC/DKIM keys';
|
||||
$lang['admin']['dkim_domains_wo_keys'] = "Select domains with missing keys";
|
||||
$lang['admin']['add'] = 'Add';
|
||||
$lang['add']['add_domain_restart'] = 'Add domain and restart SOGo';
|
||||
$lang['add']['add_domain_only'] = 'Add domain only';
|
||||
|
|
Loading…
Reference in New Issue