[Compose] Update watchdog image
[Watchdog] Fix IP detection with multiple networks [Web] Show API field (no docs, no support, wip) [Web] haveibeenpwned.com implementation [Web] User and domain admin ACL (no docs, no support, wip) [Web] Some minor fixesmaster
parent
ea4a26eabf
commit
c9554ca022
|
@ -59,10 +59,10 @@ function mail_error() {
|
|||
log_msg "Sent notification email to ${1}"
|
||||
}
|
||||
|
||||
|
||||
get_container_ip() {
|
||||
# ${1} is container
|
||||
CONTAINER_ID=()
|
||||
CONTAINER_IPS=()
|
||||
CONTAINER_IP=
|
||||
LOOP_C=1
|
||||
until [[ ${CONTAINER_IP} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] || [[ ${LOOP_C} -gt 5 ]]; do
|
||||
|
@ -72,15 +72,21 @@ get_container_ip() {
|
|||
# returned id can have multiple elements (if scaled), shuffle for random test
|
||||
CONTAINER_ID=($(printf "%s\n" "${CONTAINER_ID[@]}" | shuf))
|
||||
if [[ ! -z ${CONTAINER_ID} ]]; then
|
||||
for matched_container in "${CONTAINER_ID[@]}"; do
|
||||
CONTAINER_IP=$(curl --silent http://dockerapi:8080/containers/${matched_container}/json | jq -r '.NetworkSettings.Networks[].IPAddress')
|
||||
# grep will do nothing if one of these vars is empty
|
||||
[[ -z ${CONTAINER_IP} ]] && continue
|
||||
[[ -z ${IPV4_NETWORK} ]] && continue
|
||||
# only return ips that are part of our network
|
||||
if ! grep -q ${IPV4_NETWORK} <(echo ${CONTAINER_IP}); then
|
||||
CONTAINER_IP=
|
||||
fi
|
||||
for matched_container in "${CONTAINER_ID[@]}"; do
|
||||
CONTAINER_IPS=($(curl --silent http://dockerapi:8080/containers/${matched_container}/json | jq -r '.NetworkSettings.Networks[].IPAddress'))
|
||||
for ip_match in "${CONTAINER_IPS[@]}"; do
|
||||
# grep will do nothing if one of these vars is empty
|
||||
[[ -z ${ip_match} ]] && continue
|
||||
[[ -z ${IPV4_NETWORK} ]] && continue
|
||||
# only return ips that are part of our network
|
||||
if ! grep -q ${IPV4_NETWORK} <(echo ${ip_match}); then
|
||||
continue
|
||||
else
|
||||
CONTAINER_IP=${ip_match}
|
||||
break
|
||||
fi
|
||||
done
|
||||
[[ ! -z ${CONTAINER_IP} ]] && break
|
||||
done
|
||||
fi
|
||||
LOOP_C=$((LOOP_C + 1))
|
||||
|
@ -88,7 +94,6 @@ get_container_ip() {
|
|||
[[ ${LOOP_C} -gt 5 ]] && echo 240.0.0.0 || echo ${CONTAINER_IP}
|
||||
}
|
||||
|
||||
# Check functions
|
||||
nginx_checks() {
|
||||
err_count=0
|
||||
diff_c=0
|
||||
|
|
|
@ -29,7 +29,7 @@ $tfa_data = get_tfa();
|
|||
<div class="form-group">
|
||||
<label class="control-label col-sm-3" for="admin_pass"><?=$lang['admin']['password'];?>:</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="password" class="form-control" name="admin_pass" id="admin_pass" placeholder="<?=$lang['admin']['unchanged_if_empty'];?>">
|
||||
<input type="password" data-hibp="true" class="form-control" name="admin_pass" id="admin_pass" placeholder="<?=$lang['admin']['unchanged_if_empty'];?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -44,7 +44,7 @@ $tfa_data = get_tfa();
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<hr>
|
||||
<legend><?=$lang['tfa']['tfa'];?></legend>
|
||||
<div class="row">
|
||||
<div class="col-sm-3 col-xs-5 text-right"><?=$lang['tfa']['tfa'];?>:</div>
|
||||
<div class="col-sm-9 col-xs-7">
|
||||
|
@ -76,12 +76,10 @@ $tfa_data = get_tfa();
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hidden panel panel-primary">
|
||||
<div class="panel-heading">API</div>
|
||||
<div class="panel-body">
|
||||
<legend data-target="#api" style="margin-top:40px;cursor:pointer" id="api_legend" unselectable="on" data-toggle="collapse">
|
||||
<span id="api_arrow" style="font-size:12px" class="rotate glyphicon glyphicon-menu-down"></span> API (experimental, work in progress)
|
||||
</legend>
|
||||
<div id="api" class="collapse">
|
||||
<form class="form-horizontal" autocapitalize="none" autocorrect="off" role="form" method="post">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-3" for="allow_from"><?=$lang['admin']['api_allow_from'];?>:</label>
|
||||
|
@ -111,6 +109,7 @@ $tfa_data = get_tfa();
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -65,12 +65,6 @@ body.modal-open {
|
|||
font-size:9pt;
|
||||
background:transparent;
|
||||
}
|
||||
.bootstrap-select {
|
||||
width: auto!important;
|
||||
}
|
||||
.table-condensed .input-sm {
|
||||
width: 100%!important;
|
||||
}
|
||||
.full-width-select {
|
||||
width: 100%!important;
|
||||
}
|
||||
|
|
|
@ -5,9 +5,6 @@ table.footable>tbody>tr.footable-empty>td {
|
|||
.pagination a {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
.panel panel-default {
|
||||
overflow: visible !important;
|
||||
}
|
||||
.btn-group {
|
||||
width: max-content;
|
||||
}
|
||||
|
|
|
@ -148,3 +148,13 @@ nav .glyphicon {
|
|||
color: #5a5a5a;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.haveibeenpwned {
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.full-width-select {
|
||||
width: 100%!important;
|
||||
}
|
|
@ -92,7 +92,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="domains"><?=$lang['edit']['domains'];?></label>
|
||||
<div class="col-sm-10">
|
||||
<select data-live-search="true" id="domains" name="domains" multiple required>
|
||||
<select data-live-search="true" class="full-width-select" id="domains" name="domains" multiple required>
|
||||
<?php
|
||||
foreach ($result['selected_domains'] as $domain):
|
||||
?>
|
||||
|
@ -111,7 +111,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
<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="">
|
||||
<input type="password" data-hibp="true" class="form-control" name="password" id="password" placeholder="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -140,6 +140,30 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form data-id="daacl" class="form-inline well" method="post">
|
||||
<div class="row">
|
||||
<div class="col-sm-1">
|
||||
<p class="help-block">ACL</p>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<div class="form-group">
|
||||
<select id="da_acl" name="da_acl" size="10" multiple>
|
||||
<?php
|
||||
$da_acls = acl('get', 'domainadmin', $domain_admin);
|
||||
foreach ($da_acls as $acl => $val):
|
||||
?>
|
||||
<option value="<?=$acl;?>" <?=($val == 1) ? 'selected' : null;?>><?=$lang['acl'][$acl];?></option>
|
||||
<?php
|
||||
endforeach;
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button class="btn btn-default" id="edit_selected" data-id="daacl" data-item="<?=htmlspecialchars($domain_admin);?>" data-api-url='edit/da-acl' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
else {
|
||||
|
@ -266,7 +290,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/rl-domain' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
|
||||
<button data-acl="<?=$_SESSION['acl']['ratelimit'];?>" 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>
|
||||
|
@ -278,14 +302,14 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
<table class="table table-striped table-condensed" id="wl_policy_domain_table"></table>
|
||||
</div>
|
||||
<div class="mass-actions-user">
|
||||
<div class="btn-group">
|
||||
<div class="btn-group" data-acl="<?=$_SESSION['acl']['spam_policy'];?>">
|
||||
<a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="policy_wl_domain" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
|
||||
<a class="btn btn-sm btn-danger" id="delete_selected" data-id="policy_wl_domain" data-api-url='delete/domain-policy' href="#"><?=$lang['mailbox']['remove'];?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<form class="form-inline" data-id="add_wl_policy_domain">
|
||||
<div class="input-group">
|
||||
<div class="input-group" data-acl="<?=$_SESSION['acl']['spam_policy'];?>">
|
||||
<input type="text" class="form-control" name="object_from" id="object_from" placeholder="*@example.org" required>
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" id="add_item" data-id="add_wl_policy_domain" data-api-url='add/domain-policy' data-api-attr='{"domain":"<?= $domain; ?>","object_list":"wl"}' href="#"><?=$lang['user']['spamfilter_table_add'];?></button>
|
||||
|
@ -300,14 +324,14 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
<table class="table table-striped table-condensed" id="bl_policy_domain_table"></table>
|
||||
</div>
|
||||
<div class="mass-actions-user">
|
||||
<div class="btn-group">
|
||||
<div class="btn-group" data-acl="<?=$_SESSION['acl']['spam_policy'];?>">
|
||||
<a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="policy_bl_domain" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
|
||||
<a class="btn btn-sm btn-danger" id="delete_selected" data-id="policy_bl_domain" data-api-url='delete/domain-policy' href="#"><?=$lang['mailbox']['remove'];?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<form class="form-inline" data-id="add_bl_policy_domain">
|
||||
<div class="input-group">
|
||||
<div class="input-group" data-acl="<?=$_SESSION['acl']['spam_policy'];?>">
|
||||
<input type="text" class="form-control" name="object_from" id="object_from" placeholder="*@example.org" required>
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" id="add_item" data-id="add_bl_policy_domain" data-api-url='add/domain-policy' data-api-attr='{"domain":"<?= $domain; ?>","object_list":"bl"}' href="#"><?=$lang['user']['spamfilter_table_add'];?></button>
|
||||
|
@ -474,7 +498,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
<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'];?>">
|
||||
<input type="password" data-hibp="true" class="form-control" name="password" id="password" placeholder="<?=$lang['edit']['unchanged_if_empty'];?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -527,6 +551,30 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form data-id="useracl" class="form-inline well" method="post">
|
||||
<div class="row">
|
||||
<div class="col-sm-1">
|
||||
<p class="help-block">ACL</p>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<div class="form-group">
|
||||
<select id="user_acl" name="user_acl" size="10" multiple>
|
||||
<?php
|
||||
$user_acls = acl('get', 'user', $mailbox);
|
||||
foreach ($user_acls as $acl => $val):
|
||||
?>
|
||||
<option value="<?=$acl;?>" <?=($val == 1) ? 'selected' : null;?>><?=$lang['acl'][$acl];?></option>
|
||||
<?php
|
||||
endforeach;
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button class="btn btn-default" id="edit_selected" data-id="useracl" data-item="<?=htmlspecialchars($mailbox);?>" data-api-url='edit/user-acl' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
@ -553,7 +601,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="password"><?=$lang['add']['password'];?></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" name="password" id="password" value="<?=htmlspecialchars($result['password'], ENT_QUOTES, 'UTF-8');?>">
|
||||
<input type="password" data-hibp="true" class="form-control" name="password" id="password" value="<?=htmlspecialchars($result['password'], ENT_QUOTES, 'UTF-8');?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -965,7 +1013,7 @@ else {
|
|||
<script type='text/javascript'>
|
||||
<?php
|
||||
$lang_user = json_encode($lang['user']);
|
||||
echo "var lang = ". $lang_user . ";\n";
|
||||
echo "var lang_user = ". $lang_user . ";\n";
|
||||
echo "var table_for_domain = '". ((isset($domain)) ? $domain : null) . "';\n";
|
||||
echo "var csrf_token = '". $_SESSION['CSRF']['TOKEN'] . "';\n";
|
||||
echo "var pagination_size = '". $PAGINATION_SIZE . "';\n";
|
||||
|
|
|
@ -12,10 +12,20 @@ logger();
|
|||
<script src="/js/formcache.min.js"></script>
|
||||
<script src="/js/google.charts.loader.js"></script>
|
||||
<script src="/js/numberedtextarea.min.js"></script>
|
||||
<script src="/js/sha1.min.js"></script>
|
||||
<script src="/js/u2f-api.js"></script>
|
||||
<script src="/js/api.js"></script>
|
||||
<script src="/js/mailcow.js"></script>
|
||||
<script>
|
||||
var loading_text = '<?= $lang['footer']['loading']; ?>'
|
||||
<?php
|
||||
$lang_footer = json_encode($lang['footer']);
|
||||
$lang_acl = json_encode($lang['acl']);
|
||||
$lang_tfa = json_encode($lang['tfa']);
|
||||
echo "var lang_footer = ". $lang_footer . ";\n";
|
||||
echo "var lang_acl = ". $lang_acl . ";\n";
|
||||
echo "var lang_tfa = ". $lang_tfa . ";\n";
|
||||
echo "var docker_timeout = ". $DOCKER_TIMEOUT * 1000 . ";\n";
|
||||
?>
|
||||
$(window).scroll(function() {
|
||||
sessionStorage.scrollTop = $(this).scrollTop();
|
||||
});
|
||||
|
@ -28,17 +38,8 @@ $(window).load(function() {
|
|||
$(".overlay").hide();
|
||||
});
|
||||
$(document).ready(function() {
|
||||
window.mailcow_alert_box = function(message, type) {
|
||||
msg = $('<span/>').text(message).text();
|
||||
if (type == 'danger') {
|
||||
auto_hide = 0;
|
||||
$('#' + localStorage.getItem("add_modal")).modal('show');
|
||||
localStorage.removeItem("add_modal");
|
||||
} else {
|
||||
auto_hide = 5000;
|
||||
}
|
||||
$.notify({message: msg},{z_index: 20000, delay: auto_hide, type: type,placement: {from: "bottom",align: "right"},animate: {enter: 'animated fadeInUp',exit: 'animated fadeOutDown'}});
|
||||
}
|
||||
// TFA, CSRF, Alerts in footer.inc.php
|
||||
// Other general functions in mailcow.js
|
||||
<?php
|
||||
$alertbox_log_parser = alertbox_log_parser($_SESSION);
|
||||
if (is_array($alertbox_log_parser)) {
|
||||
|
@ -50,7 +51,6 @@ $(document).ready(function() {
|
|||
unset($_SESSION['return']);
|
||||
}
|
||||
?>
|
||||
$('[data-cached-form="true"]').formcache({key: $(this).data('id')});
|
||||
// Confirm TFA modal
|
||||
<?php if (isset($_SESSION['pending_tfa_method'])):?>
|
||||
$('#ConfirmTFAModal').modal({
|
||||
|
@ -68,7 +68,7 @@ $(document).ready(function() {
|
|||
dataType: 'script',
|
||||
url: "/api/v1/get/u2f-authentication/<?= (isset($_SESSION['pending_mailcow_cc_username'])) ? rawurlencode($_SESSION['pending_mailcow_cc_username']) : null; ?>",
|
||||
complete: function(data){
|
||||
$('#u2f_status_auth').html('<?=$lang['tfa']['waiting_usb_auth'];?>');
|
||||
$('#u2f_status_auth').html(lang_tfa.waiting_usb_auth);
|
||||
data;
|
||||
setTimeout(function() {
|
||||
console.log("Ready to authenticate");
|
||||
|
@ -98,7 +98,6 @@ $(document).ready(function() {
|
|||
<?php endif; ?>
|
||||
|
||||
// Set TFA modals
|
||||
|
||||
$('#selectTFA').change(function () {
|
||||
if ($(this).val() == "yubi_otp") {
|
||||
$('#YubiOTPModal').modal('show');
|
||||
|
@ -121,7 +120,7 @@ $(document).ready(function() {
|
|||
data;
|
||||
setTimeout(function() {
|
||||
console.log("Ready to register");
|
||||
$('#u2f_status_reg').html('<?=$lang['tfa']['waiting_usb_register'];?>');
|
||||
$('#u2f_status_reg').html(lang_tfa.waiting_usb_register);
|
||||
u2f.register(appId, registerRequests, registeredKeys, function(deviceResponse) {
|
||||
var form = document.getElementById('u2f_reg_form');
|
||||
var reg = document.getElementById('u2f_register_data');
|
||||
|
@ -146,92 +145,6 @@ $(document).ready(function() {
|
|||
}
|
||||
});
|
||||
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
});
|
||||
|
||||
// Remember last navigation pill
|
||||
(function () {
|
||||
'use strict';
|
||||
if ($('a[data-toggle="tab"]').length) {
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
if ($(this).data('dont-remember') == 1) {
|
||||
return true;
|
||||
}
|
||||
var id = $(this).parents('[role="tablist"]').attr('id');
|
||||
var key = 'lastTag';
|
||||
if (id) {
|
||||
key += ':' + id;
|
||||
}
|
||||
localStorage.setItem(key, $(e.target).attr('href'));
|
||||
});
|
||||
$('[role="tablist"]').each(function (idx, elem) {
|
||||
var id = $(elem).attr('id');
|
||||
var key = 'lastTag';
|
||||
if (id) {
|
||||
key += ':' + id;
|
||||
}
|
||||
var lastTab = localStorage.getItem(key);
|
||||
if (lastTab) {
|
||||
$('[href="' + lastTab + '"]').tab('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
// Disable submit after submitting form (not API driven buttons)
|
||||
$('form').submit(function() {
|
||||
if ($('form button[type="submit"]').data('submitted') == '1') {
|
||||
return false;
|
||||
} else {
|
||||
$(this).find('button[type="submit"]').first().text('<?= $lang['footer']['loading']; ?>');
|
||||
$('form button[type="submit"]').attr('data-submitted', '1');
|
||||
function disableF5(e) { if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) e.preventDefault(); };
|
||||
$(document).on("keydown", disableF5);
|
||||
}
|
||||
});
|
||||
|
||||
// IE fix to hide scrollbars when table body is empty
|
||||
$('tbody').filter(function (index) {
|
||||
return $(this).children().length < 1;
|
||||
}).remove();
|
||||
|
||||
// Init Bootstrap Selectpicker
|
||||
$('select').selectpicker();
|
||||
|
||||
// Trigger container restart
|
||||
$('#RestartContainer').on('show.bs.modal', function(e) {
|
||||
var container = $(e.relatedTarget).data('container');
|
||||
$('#containerName').text(container);
|
||||
$('#triggerRestartContainer').click(function(){
|
||||
$(this).prop("disabled",true);
|
||||
$(this).html('<span class="glyphicon glyphicon-refresh glyphicon-spin"></span> ');
|
||||
$('#statusTriggerRestartContainer').html('<?= $lang['footer']['restarting_container']; ?>');
|
||||
$.ajax({
|
||||
method: 'get',
|
||||
url: '/inc/ajax/container_ctrl.php',
|
||||
timeout: <?= $DOCKER_TIMEOUT * 1000; ?>,
|
||||
data: {
|
||||
'service': container,
|
||||
'action': 'restart'
|
||||
}
|
||||
})
|
||||
.always( function (data, status) {
|
||||
$('#statusTriggerRestartContainer').append(data);
|
||||
var htmlResponse = $.parseHTML(data)
|
||||
if ($(htmlResponse).find('span').hasClass('text-success')) {
|
||||
$('#triggerRestartContainer').html('<span class="glyphicon glyphicon-ok"></span> ');
|
||||
setTimeout(function(){
|
||||
$('#RestartContainer').modal('toggle');
|
||||
window.location = window.location.href.split("#")[0];
|
||||
}, 1200);
|
||||
} else {
|
||||
$('#triggerRestartContainer').html('<span class="glyphicon glyphicon-remove"></span> ');
|
||||
}
|
||||
})
|
||||
});
|
||||
})
|
||||
|
||||
// CSRF
|
||||
$('<input type="hidden" value="<?= $_SESSION['CSRF']['TOKEN']; ?>">').attr('id', 'csrf_token').attr('name', 'csrf_token').appendTo('form');
|
||||
if (sessionStorage.scrollTop != "undefined") {
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
<?php
|
||||
function acl($_action, $_scope = null, $_data = null) {
|
||||
global $pdo;
|
||||
global $lang;
|
||||
$_data_log = $_data;
|
||||
switch ($_action) {
|
||||
case 'edit':
|
||||
switch ($_scope) {
|
||||
case 'user':
|
||||
if (!is_array($_data['username'])) {
|
||||
$usernames = array();
|
||||
$usernames[] = $_data['username'];
|
||||
}
|
||||
else {
|
||||
$usernames = $_data['username'];
|
||||
}
|
||||
foreach ($usernames as $username) {
|
||||
// Cast to array for single selections
|
||||
$acls = (array)$_data['user_acl'];
|
||||
// Create associative array from index array
|
||||
// All set items are given 1 as value
|
||||
foreach ($acls as $acl_key => $acl_val) {
|
||||
$acl_post[$acl_val] = 1;
|
||||
}
|
||||
// Users cannot change their own ACL
|
||||
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)
|
||||
|| ($_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;
|
||||
}
|
||||
// Read all available acl options by calling acl(get)
|
||||
// Set all available acl options we cannot find in the post data to 0, else 1
|
||||
$is_now = acl('get', 'user', $username);
|
||||
if (!empty($is_now)) {
|
||||
foreach ($is_now as $acl_now_name => $acl_now_val) {
|
||||
$set_acls[$acl_now_name] = (isset($acl_post[$acl_now_name])) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => 'Cannot determine current ACL'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
foreach ($set_acls as $set_acl_key => $set_acl_val) {
|
||||
$stmt = $pdo->prepare("UPDATE `user_acl` SET " . $set_acl_key . " = " . intval($set_acl_val) . "
|
||||
WHERE `username` = :username");
|
||||
$stmt->execute(array(
|
||||
':username' => $username,
|
||||
));
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => array('acl_saved', $username)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'domainadmin':
|
||||
if ($_SESSION['mailcow_cc_role'] != 'admin') {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (!is_array($_data['username'])) {
|
||||
$usernames = array();
|
||||
$usernames[] = $_data['username'];
|
||||
}
|
||||
else {
|
||||
$usernames = $_data['username'];
|
||||
}
|
||||
foreach ($usernames as $username) {
|
||||
// Cast to array for single selections
|
||||
$acls = (array)$_data['da_acl'];
|
||||
// Create associative array from index array
|
||||
// All set items are given 1 as value
|
||||
foreach ($acls as $acl_key => $acl_val) {
|
||||
$acl_post[$acl_val] = 1;
|
||||
}
|
||||
// Users cannot change their own ACL
|
||||
if ($_SESSION['mailcow_cc_role'] != 'admin') {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
// Read all available acl options by calling acl(get)
|
||||
// Set all available acl options we cannot find in the post data to 0, else 1
|
||||
$is_now = acl('get', 'domainadmin', $username);
|
||||
if (!empty($is_now)) {
|
||||
foreach ($is_now as $acl_now_name => $acl_now_val) {
|
||||
$set_acls[$acl_now_name] = (isset($acl_post[$acl_now_name])) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => 'Cannot determine current ACL'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
foreach ($set_acls as $set_acl_key => $set_acl_val) {
|
||||
$stmt = $pdo->prepare("UPDATE `da_acl` SET " . $set_acl_key . " = " . intval($set_acl_val) . "
|
||||
WHERE `username` = :username");
|
||||
$stmt->execute(array(
|
||||
':username' => $username,
|
||||
));
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => array('acl_saved', $username)
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'get':
|
||||
switch ($_scope) {
|
||||
case 'user':
|
||||
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
|
||||
return false;
|
||||
}
|
||||
$stmt = $pdo->prepare("SELECT * FROM `user_acl` WHERE `username` = :username");
|
||||
$stmt->execute(array(':username' => $_data));
|
||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!empty($data)) {
|
||||
unset($data['username']);
|
||||
return $data;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'domainadmin':
|
||||
if ($_SESSION['mailcow_cc_role'] != 'admin' && $_SESSION['mailcow_cc_role'] != 'domainadmin') {
|
||||
return false;
|
||||
}
|
||||
if ($_SESSION['mailcow_cc_role'] == 'domainadmin' && $_SESSION['mailcow_cc_username'] != $_data) {
|
||||
return false;
|
||||
}
|
||||
$stmt = $pdo->prepare("SELECT * FROM `da_acl` WHERE `username` = :username");
|
||||
$stmt->execute(array(':username' => $_data));
|
||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!empty($data)) {
|
||||
unset($data['username']);
|
||||
return $data;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'to_session':
|
||||
if (!isset($_SESSION['mailcow_cc_role'])) {
|
||||
return false;
|
||||
}
|
||||
unset($_SESSION['acl']);
|
||||
$username = strtolower(trim($_SESSION['mailcow_cc_username']));
|
||||
// Admins get access to all modules
|
||||
if ($_SESSION['mailcow_cc_role'] == 'admin' ||
|
||||
(isset($_SESSION["dual-login"]["role"]) && $_SESSION["dual-login"]["role"] == 'admin')) {
|
||||
$stmt = $pdo->query("SHOW COLUMNS FROM `user_acl` WHERE `Field` != 'username';");
|
||||
$acl_all = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
while ($row = array_shift($acl_all)) {
|
||||
$acl['acl'][$row['Field']] = 1;
|
||||
}
|
||||
$stmt = $pdo->query("SHOW COLUMNS FROM `da_acl` WHERE `Field` != 'username';");
|
||||
$acl_all = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
while ($row = array_shift($acl_all)) {
|
||||
$acl['acl'][$row['Field']] = 1;
|
||||
}
|
||||
}
|
||||
elseif ($_SESSION['mailcow_cc_role'] == 'domainadmin' ||
|
||||
(isset($_SESSION["dual-login"]["role"]) && $_SESSION["dual-login"]["role"] == 'domainadmin')) {
|
||||
// Read all exting user_acl modules and set to 1
|
||||
$stmt = $pdo->query("SHOW COLUMNS FROM `user_acl` WHERE `Field` != 'username';");
|
||||
$acl_all = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
while ($row = array_shift($acl_all)) {
|
||||
$acl['acl'][$row['Field']] = 1;
|
||||
}
|
||||
// Read da_acl rules for current user, OVERWRITE overlapping modules
|
||||
// This prevents access to a users sync jobs, when a domain admins was not given access to sync jobs
|
||||
$stmt = $pdo->prepare("SELECT * FROM `da_acl` WHERE `username` = :username");
|
||||
$stmt->execute(array(':username' => (isset($_SESSION["dual-login"]["username"])) ? $_SESSION["dual-login"]["username"] : $username));
|
||||
$acl_user = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
foreach ($acl_user as $acl_user_key => $acl_user_val) {
|
||||
$acl['acl'][$acl_user_key] = $acl_user_val;
|
||||
}
|
||||
unset($acl['acl']['username']);
|
||||
}
|
||||
elseif ($_SESSION['mailcow_cc_role'] == 'user') {
|
||||
$stmt = $pdo->prepare("SELECT * FROM `user_acl` WHERE `username` = :username");
|
||||
$stmt->execute(array(':username' => $username));
|
||||
$acl['acl'] = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
unset($acl['acl']['username']);
|
||||
}
|
||||
if (!empty($acl)) {
|
||||
$_SESSION = array_merge($_SESSION, $acl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -233,6 +233,14 @@ function bcc($_action, $_data = null, $attr = null) {
|
|||
return $bccdata;
|
||||
break;
|
||||
case 'delete':
|
||||
if (!isset($_SESSION['acl']['bcc_maps']) || $_SESSION['acl']['bcc_maps'] != "1" ) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data, $_attr),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$ids = (array)$_data['id'];
|
||||
foreach ($ids as $id) {
|
||||
if (!is_numeric($id)) {
|
||||
|
@ -279,6 +287,14 @@ function recipient_map($_action, $_data = null, $attr = null) {
|
|||
}
|
||||
switch ($_action) {
|
||||
case 'add':
|
||||
if (!isset($_SESSION['acl']['recipient_maps']) || $_SESSION['acl']['recipient_maps'] != "1" ) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data, $_attr),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$old_dest = strtolower(trim($_data['recipient_map_old']));
|
||||
if (substr($old_dest, 0, 1) == '@') {
|
||||
$old_dest = substr($old_dest, 1);
|
||||
|
@ -343,6 +359,14 @@ function recipient_map($_action, $_data = null, $attr = null) {
|
|||
);
|
||||
break;
|
||||
case 'edit':
|
||||
if (!isset($_SESSION['acl']['recipient_maps']) || $_SESSION['acl']['recipient_maps'] != "1" ) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data, $_attr),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$ids = (array)$_data['id'];
|
||||
foreach ($ids as $id) {
|
||||
$is_now = recipient_map('details', $id);
|
||||
|
@ -458,6 +482,14 @@ function recipient_map($_action, $_data = null, $attr = null) {
|
|||
return $mapdata;
|
||||
break;
|
||||
case 'delete':
|
||||
if (!isset($_SESSION['acl']['recipient_maps']) || $_SESSION['acl']['recipient_maps'] != "1" ) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data, $_attr),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$ids = (array)$_data['id'];
|
||||
foreach ($ids as $id) {
|
||||
if (!is_numeric($id)) {
|
||||
|
|
|
@ -90,43 +90,22 @@ function domain_admin($_action, $_data = null) {
|
|||
);
|
||||
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) {
|
||||
domain_admin('delete', $username);
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data_log),
|
||||
'msg' => array('mysql_error', $e)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
try {
|
||||
$stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `active`)
|
||||
VALUES (:username, :password_hashed, '0', :active)");
|
||||
$stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
|
||||
VALUES (:username, :domain, :created, :active)");
|
||||
$stmt->execute(array(
|
||||
':username' => $username,
|
||||
':password_hashed' => $password_hashed,
|
||||
':domain' => $domain,
|
||||
':created' => date('Y-m-d H:i:s'),
|
||||
':active' => $active
|
||||
));
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data_log),
|
||||
'msg' => array('mysql_error', $e)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `active`)
|
||||
VALUES (:username, :password_hashed, '0', :active)");
|
||||
$stmt->execute(array(
|
||||
':username' => $username,
|
||||
':password_hashed' => $password_hashed,
|
||||
':active' => $active
|
||||
));
|
||||
}
|
||||
else {
|
||||
$_SESSION['return'][] = array(
|
||||
|
@ -136,6 +115,10 @@ function domain_admin($_action, $_data = null) {
|
|||
);
|
||||
return false;
|
||||
}
|
||||
$stmt = $pdo->prepare("INSERT INTO `da_acl` (`username`) VALUES (:username)");
|
||||
$stmt->execute(array(
|
||||
':username' => $username
|
||||
));
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_data_log),
|
||||
|
@ -209,41 +192,20 @@ function domain_admin($_action, $_data = null) {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
try {
|
||||
$stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
|
||||
$stmt->execute(array(
|
||||
':username' => $username,
|
||||
));
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data_log),
|
||||
'msg' => array('mysql_error', $e)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
|
||||
$stmt->execute(array(
|
||||
':username' => $username,
|
||||
));
|
||||
if (!empty($domains)) {
|
||||
foreach ($domains as $domain) {
|
||||
try {
|
||||
$stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
|
||||
VALUES (:username_new, :domain, :created, :active)");
|
||||
$stmt->execute(array(
|
||||
':username_new' => $username_new,
|
||||
':domain' => $domain,
|
||||
':created' => date('Y-m-d H:i:s'),
|
||||
':active' => $active
|
||||
));
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data_log),
|
||||
'msg' => array('mysql_error', $e)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
$stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
|
||||
VALUES (:username_new, :domain, :created, :active)");
|
||||
$stmt->execute(array(
|
||||
':username_new' => $username_new,
|
||||
':domain' => $domain,
|
||||
':created' => date('Y-m-d H:i:s'),
|
||||
':active' => $active
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,56 +227,36 @@ function domain_admin($_action, $_data = null) {
|
|||
continue;
|
||||
}
|
||||
$password_hashed = hash_password($password);
|
||||
try {
|
||||
$stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username_new, `active` = :active, `password` = :password_hashed WHERE `username` = :username");
|
||||
$stmt->execute(array(
|
||||
':password_hashed' => $password_hashed,
|
||||
':username_new' => $username_new,
|
||||
':username' => $username,
|
||||
':active' => $active
|
||||
));
|
||||
if (isset($_data['disable_tfa'])) {
|
||||
$stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
|
||||
$stmt->execute(array(':username' => $username));
|
||||
}
|
||||
else {
|
||||
$stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username_new WHERE `username` = :username");
|
||||
$stmt->execute(array(':username_new' => $username_new, ':username' => $username));
|
||||
}
|
||||
$stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username_new, `active` = :active, `password` = :password_hashed WHERE `username` = :username");
|
||||
$stmt->execute(array(
|
||||
':password_hashed' => $password_hashed,
|
||||
':username_new' => $username_new,
|
||||
':username' => $username,
|
||||
':active' => $active
|
||||
));
|
||||
if (isset($_data['disable_tfa'])) {
|
||||
$stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
|
||||
$stmt->execute(array(':username' => $username));
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data_log),
|
||||
'msg' => array('mysql_error', $e)
|
||||
);
|
||||
continue;
|
||||
else {
|
||||
$stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username_new WHERE `username` = :username");
|
||||
$stmt->execute(array(':username_new' => $username_new, ':username' => $username));
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username_new, `active` = :active WHERE `username` = :username");
|
||||
$stmt->execute(array(
|
||||
':username_new' => $username_new,
|
||||
':username' => $username,
|
||||
':active' => $active
|
||||
));
|
||||
if (isset($_data['disable_tfa'])) {
|
||||
$stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
|
||||
$stmt->execute(array(':username' => $username));
|
||||
}
|
||||
else {
|
||||
$stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username_new WHERE `username` = :username");
|
||||
$stmt->execute(array(':username_new' => $username_new, ':username' => $username));
|
||||
}
|
||||
$stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username_new, `active` = :active WHERE `username` = :username");
|
||||
$stmt->execute(array(
|
||||
':username_new' => $username_new,
|
||||
':username' => $username,
|
||||
':active' => $active
|
||||
));
|
||||
if (isset($_data['disable_tfa'])) {
|
||||
$stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
|
||||
$stmt->execute(array(':username' => $username));
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data_log),
|
||||
'msg' => array('mysql_error', $e)
|
||||
);
|
||||
continue;
|
||||
else {
|
||||
$stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username_new WHERE `username` = :username");
|
||||
$stmt->execute(array(':username_new' => $username_new, ':username' => $username));
|
||||
}
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
|
@ -365,21 +307,11 @@ function domain_admin($_action, $_data = null) {
|
|||
return false;
|
||||
}
|
||||
$password_hashed = hash_password($password_new);
|
||||
try {
|
||||
$stmt = $pdo->prepare("UPDATE `admin` SET `password` = :password_hashed WHERE `username` = :username");
|
||||
$stmt->execute(array(
|
||||
':password_hashed' => $password_hashed,
|
||||
':username' => $username
|
||||
));
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_data_log),
|
||||
'msg' => array('mysql_error', $e)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$stmt = $pdo->prepare("UPDATE `admin` SET `password` = :password_hashed WHERE `username` = :username");
|
||||
$stmt->execute(array(
|
||||
':password_hashed' => $password_hashed,
|
||||
':username' => $username
|
||||
));
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
|
@ -407,24 +339,14 @@ function domain_admin($_action, $_data = null) {
|
|||
);
|
||||
continue;
|
||||
}
|
||||
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',
|
||||
'log' => array(__FUNCTION__, $_action, $_data_log),
|
||||
'msg' => array('mysql_error', $e)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
$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,
|
||||
));
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_action, $_data_log),
|
||||
|
|
|
@ -373,54 +373,6 @@ function check_login($user, $pass) {
|
|||
sleep($_SESSION['ldelay']);
|
||||
return false;
|
||||
}
|
||||
function set_acl() {
|
||||
global $pdo;
|
||||
if (!isset($_SESSION['mailcow_cc_username'])) {
|
||||
return false;
|
||||
}
|
||||
if ($_SESSION['mailcow_cc_role'] == 'admin' || $_SESSION['mailcow_cc_role'] == 'domainadmin') {
|
||||
$stmt = $pdo->query("SHOW COLUMNS FROM `user_acl` WHERE `Field` != 'username';");
|
||||
$acl_all = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
while ($row = array_shift($acl_all)) {
|
||||
$acl['acl'][$row['Field']] = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$username = strtolower(trim($_SESSION['mailcow_cc_username']));
|
||||
$stmt = $pdo->prepare("SELECT * FROM `user_acl` WHERE `username` = :username");
|
||||
$stmt->execute(array(':username' => $username));
|
||||
$acl['acl'] = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
unset($acl['acl']['username']);
|
||||
}
|
||||
if (!empty($acl)) {
|
||||
$_SESSION = array_merge($_SESSION, $acl);
|
||||
}
|
||||
else {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'info',
|
||||
'log' => array(__FUNCTION__),
|
||||
'msg' => 'set_acl_failed'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function get_acl($username) {
|
||||
global $pdo;
|
||||
if ($_SESSION['mailcow_cc_role'] != "admin") {
|
||||
return false;
|
||||
}
|
||||
$username = strtolower(trim($username));
|
||||
$stmt = $pdo->prepare("SELECT * FROM `user_acl` WHERE `username` = :username");
|
||||
$stmt->execute(array(':username' => $username));
|
||||
$acl = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
unset($acl['username']);
|
||||
if (!empty($acl)) {
|
||||
return $acl;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function formatBytes($size, $precision = 2) {
|
||||
if(!is_numeric($size)) {
|
||||
return "0";
|
||||
|
@ -1266,7 +1218,7 @@ function get_admin_details() {
|
|||
return false;
|
||||
}
|
||||
$stmt = $pdo->query("SELECT `admin`.`username`, `api`.`active` AS `api_active`, `api`.`api_key`, `api`.`allow_from` FROM `admin`
|
||||
INNER JOIN `api` ON `admin`.`username` = `api`.`username`
|
||||
LEFT OUTER JOIN `api` ON `admin`.`username` = `api`.`username`
|
||||
WHERE `admin`.`superadmin`='1'
|
||||
AND `admin`.`active`='1'");
|
||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
|
|
@ -139,7 +139,6 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||
$stmt = $pdo->prepare("UPDATE `sieve_filters` SET `script_name` = 'inactive' WHERE `username` = :username AND `filter_type` = :filter_type");
|
||||
$stmt->execute(array(
|
||||
':username' => $username,
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
':filter_type' => $filter_type
|
||||
));
|
||||
}
|
||||
|
@ -1453,14 +1452,6 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||
}
|
||||
break;
|
||||
case 'filter':
|
||||
$sieve = new Sieve\SieveParser();
|
||||
if (!is_array($_data['id'])) {
|
||||
$ids = array();
|
||||
$ids[] = $_data['id'];
|
||||
}
|
||||
else {
|
||||
$ids = $_data['id'];
|
||||
}
|
||||
if (!isset($_SESSION['acl']['filters']) || $_SESSION['acl']['filters'] != "1" ) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
|
@ -1469,6 +1460,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||
);
|
||||
return false;
|
||||
}
|
||||
$sieve = new Sieve\SieveParser();
|
||||
if (!is_array($_data['id'])) {
|
||||
$ids = array();
|
||||
$ids[] = $_data['id'];
|
||||
}
|
||||
else {
|
||||
$ids = $_data['id'];
|
||||
}
|
||||
foreach ($ids as $id) {
|
||||
$is_now = mailbox('get', 'filter_details', $id);
|
||||
if (!empty($is_now)) {
|
||||
|
|
|
@ -6,6 +6,14 @@ function policy($_action, $_scope, $_data = null) {
|
|||
$_data_log = $_data;
|
||||
switch ($_action) {
|
||||
case 'add':
|
||||
if (!isset($_SESSION['acl']['spam_policy']) || $_SESSION['acl']['spam_policy'] != "1" ) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
switch ($_scope) {
|
||||
case 'domain':
|
||||
$object = $_data['domain'];
|
||||
|
@ -90,14 +98,6 @@ function policy($_action, $_scope, $_data = null) {
|
|||
);
|
||||
return false;
|
||||
}
|
||||
if (!isset($_SESSION['acl']['spam_policy']) || $_SESSION['acl']['spam_policy'] != "1" ) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if ($_data['object_list'] == "bl") {
|
||||
$object_list = "blacklist_from";
|
||||
}
|
||||
|
@ -151,6 +151,14 @@ function policy($_action, $_scope, $_data = null) {
|
|||
}
|
||||
break;
|
||||
case 'delete':
|
||||
if (!isset($_SESSION['acl']['spam_policy']) || $_SESSION['acl']['spam_policy'] != "1" ) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
switch ($_scope) {
|
||||
case 'domain':
|
||||
(array)$prefids = $_data['prefid'];
|
||||
|
@ -215,14 +223,6 @@ function policy($_action, $_scope, $_data = null) {
|
|||
else {
|
||||
$prefids = $_data['prefid'];
|
||||
}
|
||||
if (!isset($_SESSION['acl']['spam_policy']) || $_SESSION['acl']['spam_policy'] != "1" ) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
foreach ($prefids as $prefid) {
|
||||
if (!is_numeric($prefid)) {
|
||||
$_SESSION['return'][] = array(
|
||||
|
|
|
@ -5,6 +5,14 @@ function ratelimit($_action, $_scope, $_data = null) {
|
|||
$_data_log = $_data;
|
||||
switch ($_action) {
|
||||
case 'edit':
|
||||
if (!isset($_SESSION['acl']['ratelimit']) || $_SESSION['acl']['ratelimit'] != "1" ) {
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'danger',
|
||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||
'msg' => 'access_denied'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
switch ($_scope) {
|
||||
case 'domain':
|
||||
if (!is_array($_data['object'])) {
|
||||
|
|
|
@ -3,7 +3,7 @@ function init_db_schema() {
|
|||
try {
|
||||
global $pdo;
|
||||
|
||||
$db_version = "19082018_1004";
|
||||
$db_version = "01092018_1902";
|
||||
|
||||
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
@ -280,10 +280,7 @@ function init_db_schema() {
|
|||
"delimiter_action" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"syncjobs" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"eas_reset" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"filters" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"quarantine" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"bcc_maps" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"recipient_maps" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||
),
|
||||
"keys" => array(
|
||||
"primary" => array(
|
||||
|
@ -300,6 +297,32 @@ function init_db_schema() {
|
|||
),
|
||||
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||
),
|
||||
"da_acl" => array(
|
||||
"cols" => array(
|
||||
"username" => "VARCHAR(255) NOT NULL",
|
||||
"syncjobs" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"quarantine" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"login_as" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"bcc_maps" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"filters" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"ratelimit" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
"spam_policy" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||
),
|
||||
"keys" => array(
|
||||
"primary" => array(
|
||||
"" => array("username")
|
||||
),
|
||||
"fkey" => array(
|
||||
"fk_domain_admin_acl" => array(
|
||||
"col" => "username",
|
||||
"ref" => "domain_admins.username",
|
||||
"delete" => "CASCADE",
|
||||
"update" => "NO ACTION"
|
||||
)
|
||||
)
|
||||
),
|
||||
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||
),
|
||||
"alias_domain" => array(
|
||||
"cols" => array(
|
||||
"alias_domain" => "VARCHAR(255) NOT NULL",
|
||||
|
@ -950,8 +973,9 @@ DELIMITER ;';
|
|||
'msg' => 'db_init_complete'
|
||||
);
|
||||
|
||||
// Fix user_acl
|
||||
// Fix ACL
|
||||
$stmt = $pdo->query("INSERT INTO `user_acl` (`username`) SELECT `username` FROM `mailbox` WHERE `kind` = '' AND NOT EXISTS (SELECT `username` FROM `user_acl`);");
|
||||
$stmt = $pdo->query("INSERT INTO `da_acl` (`username`) SELECT DISTINCT `username` FROM `domain_admins` WHERE `username` != 'admin' AND NOT EXISTS (SELECT `username` FROM `da_acl`);");
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
$_SESSION['return'][] = array(
|
||||
|
|
|
@ -124,6 +124,7 @@ if (isset($_GET['lang']) && in_array($_GET['lang'], $AVAILABLE_LANGUAGES)) {
|
|||
require_once $_SERVER['DOCUMENT_ROOT'] . '/lang/lang.en.php';
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/lang/lang.'.$_SESSION['mailcow_locale'].'.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.inc.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.acl.inc.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.mailbox.inc.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.customize.inc.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.address_rewriting.inc.php';
|
||||
|
@ -141,6 +142,6 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/init_db.inc.php';
|
|||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.inc.php';
|
||||
init_db_schema();
|
||||
if (isset($_SESSION['mailcow_cc_role'])) {
|
||||
set_acl();
|
||||
acl('to_session');
|
||||
}
|
||||
$UI_TEXTS = customize('get', 'ui_texts');
|
||||
|
|
|
@ -40,7 +40,7 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) {
|
|||
}
|
||||
}
|
||||
|
||||
if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admin") {
|
||||
if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['acl']['login_as'] == "1") {
|
||||
if (isset($_GET["duallogin"])) {
|
||||
$duallogin = html_entity_decode(rawurldecode($_GET["duallogin"]));
|
||||
if (filter_var($duallogin, FILTER_VALIDATE_EMAIL)) {
|
||||
|
|
|
@ -13,6 +13,10 @@ jQuery(function($){
|
|||
e.preventDefault();
|
||||
$('#duplicate_dkim_arrow').toggleClass("animation");
|
||||
});
|
||||
$("#api_legend").on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$('#api_arrow').toggleClass("animation");
|
||||
});
|
||||
$("#rspamd_preset_1").on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$("form[data-id=rsetting]").find("#desc").val(lang.rsettings_preset_1);
|
||||
|
|
|
@ -5,9 +5,9 @@ $(document).ready(function() {
|
|||
} else {
|
||||
var parent_btn_grp = $(elem).parentsUntil(".btn-group").parent();
|
||||
if (parent_btn_grp.hasClass('btn-group')) {
|
||||
parent_btn_grp.replaceWith('<button class="btn btn-default btn-sm" disabled>' + loading_text + '</a>');
|
||||
parent_btn_grp.replaceWith('<button class="btn btn-default btn-sm" disabled>' + lang_footer.loading + '</a>');
|
||||
}
|
||||
$(elem).text(loading_text);
|
||||
$(elem).text(lang_footer.loading);
|
||||
$(elem).attr('data-submitted', '1');
|
||||
function disableF5(e) { if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) e.preventDefault(); };
|
||||
$(document).on("keydown", disableF5);
|
||||
|
|
|
@ -61,10 +61,10 @@ jQuery(function($){
|
|||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
|
||||
{"sorted": true,"name":"value","title":lang.spamfilter_table_rule},
|
||||
{"sorted": true,"name":"value","title":lang_user.spamfilter_table_rule},
|
||||
{"name":"object","title":"Scope"}
|
||||
],
|
||||
"empty": lang.empty,
|
||||
"empty": lang_user.empty,
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
url: '/api/v1/get/policy_wl_domain/' + table_for_domain,
|
||||
|
@ -78,7 +78,7 @@ jQuery(function($){
|
|||
item.chkbox = '<input type="checkbox" data-id="policy_wl_domain" name="multi_select" value="' + item.prefid + '" />';
|
||||
}
|
||||
else {
|
||||
item.chkbox = '<input type="checkbox" disabled title="' + lang.spamfilter_table_domain_policy + '" />';
|
||||
item.chkbox = '<input type="checkbox" disabled title="' + lang_user.spamfilter_table_domain_policy + '" />';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -98,10 +98,10 @@ jQuery(function($){
|
|||
"columns": [
|
||||
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
|
||||
{"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
|
||||
{"sorted": true,"name":"value","title":lang.spamfilter_table_rule},
|
||||
{"sorted": true,"name":"value","title":lang_user.spamfilter_table_rule},
|
||||
{"name":"object","title":"Scope"}
|
||||
],
|
||||
"empty": lang.empty,
|
||||
"empty": lang_user.empty,
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
url: '/api/v1/get/policy_bl_domain/' + table_for_domain,
|
||||
|
@ -115,7 +115,7 @@ jQuery(function($){
|
|||
item.chkbox = '<input type="checkbox" data-id="policy_bl_domain" name="multi_select" value="' + item.prefid + '" />';
|
||||
}
|
||||
else {
|
||||
item.chkbox = '<input type="checkbox" disabled tooltip="' + lang.spamfilter_table_domain_policy + '" />';
|
||||
item.chkbox = '<input type="checkbox" disabled tooltip="' + lang_user.spamfilter_table_domain_policy + '" />';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
$(document).ready(function() {
|
||||
acl_data = JSON.parse(acl);
|
||||
FooTable.domainFilter = FooTable.Filtering.extend({
|
||||
construct: function(instance){
|
||||
this._super(instance);
|
||||
|
@ -82,6 +83,7 @@ $(document).ready(function() {
|
|||
|
||||
$(".generate_password").click(function( event ) {
|
||||
event.preventDefault();
|
||||
$('[data-hibp]').trigger('input');
|
||||
var random_passwd = Math.random().toString(36).slice(-8)
|
||||
$('#password').prop('type', 'text');
|
||||
$('#password').val(random_passwd);
|
||||
|
@ -233,6 +235,13 @@ jQuery(function($){
|
|||
eval(draw_table + '()');
|
||||
});
|
||||
function table_mailbox_ready(ft, name) {
|
||||
if(is_dual) {
|
||||
$('.login_as').data("toggle", "tooltip")
|
||||
.attr("disabled", true)
|
||||
.removeAttr("href")
|
||||
.attr("title", "Dual login cannot be used twice")
|
||||
.tooltip();
|
||||
}
|
||||
heading = ft.$el.parents('.tab-pane').find('.panel-heading')
|
||||
var ft_paging = ft.use(FooTable.Paging)
|
||||
$(heading).children('.table-lines').text(function(){
|
||||
|
@ -264,10 +273,10 @@ 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":"rl","title":"RL","breakpoints":"xs sm md","style":{"maxWidth":"100px","width":"100px"}},
|
||||
{"name":"backupmx","filterable": false,"style":{"maxWidth":"120px","width":"120px"},"title":lang.backup_mx,"breakpoints":"xs sm md"},
|
||||
{"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"}
|
||||
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"240px","width":"240px"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
|
||||
],
|
||||
"rows": $.ajax({
|
||||
dataType: 'json',
|
||||
|
@ -374,11 +383,11 @@ jQuery(function($){
|
|||
}).join('/1');
|
||||
}
|
||||
item.chkbox = '<input type="checkbox" data-id="mailbox" name="multi_select" value="' + encodeURIComponent(item.username) + '" />';
|
||||
if (role == "admin") {
|
||||
if (acl_data.login_as === 1) {
|
||||
item.action = '<div class="btn-group">' +
|
||||
'<a href="/edit.php?mailbox=' + encodeURIComponent(item.username) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
|
||||
'<a href="#" id="delete_selected" data-id="single-mailbox" data-api-url="delete/mailbox" data-item="' + encodeURIComponent(item.username) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
|
||||
'<a href="/index.php?duallogin=' + encodeURIComponent(item.username) + '" class="btn btn-xs btn-success"><span class="glyphicon glyphicon-user"></span> Login</a>' +
|
||||
'<a href="/index.php?duallogin=' + encodeURIComponent(item.username) + '" class="login_as btn btn-xs btn-success"><span class="glyphicon glyphicon-user"></span> Login</a>' +
|
||||
'</div>';
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
$(document).ready(function() {
|
||||
// mailcow alert box generator
|
||||
window.mailcow_alert_box = function(message, type) {
|
||||
msg = $('<span/>').text(message).text();
|
||||
if (type == 'danger') {
|
||||
auto_hide = 0;
|
||||
$('#' + localStorage.getItem("add_modal")).modal('show');
|
||||
localStorage.removeItem("add_modal");
|
||||
} else {
|
||||
auto_hide = 5000;
|
||||
}
|
||||
$.notify({message: msg},{z_index: 20000, delay: auto_hide, type: type,placement: {from: "bottom",align: "right"},animate: {enter: 'animated fadeInUp',exit: 'animated fadeOutDown'}});
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/4399005/implementing-jquerys-shake-effect-with-animate
|
||||
function shake(div,interval=100,distance=10,times=4) {
|
||||
$(div).css('position','relative');
|
||||
for(var iter=0;iter<(times+1);iter++){
|
||||
$(div).animate({ left: ((iter%2==0 ? distance : distance*-1))}, interval);
|
||||
}
|
||||
$(div).animate({ left: 0},interval);
|
||||
}
|
||||
|
||||
// form cache
|
||||
$('[data-cached-form="true"]').formcache({key: $(this).data('id')});
|
||||
|
||||
// tooltips
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
});
|
||||
|
||||
// remember last navigation pill
|
||||
(function () {
|
||||
'use strict';
|
||||
if ($('a[data-toggle="tab"]').length) {
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
if ($(this).data('dont-remember') == 1) {
|
||||
return true;
|
||||
}
|
||||
var id = $(this).parents('[role="tablist"]').attr('id');
|
||||
var key = 'lastTag';
|
||||
if (id) {
|
||||
key += ':' + id;
|
||||
}
|
||||
localStorage.setItem(key, $(e.target).attr('href'));
|
||||
});
|
||||
$('[role="tablist"]').each(function (idx, elem) {
|
||||
var id = $(elem).attr('id');
|
||||
var key = 'lastTag';
|
||||
if (id) {
|
||||
key += ':' + id;
|
||||
}
|
||||
var lastTab = localStorage.getItem(key);
|
||||
if (lastTab) {
|
||||
$('[href="' + lastTab + '"]').tab('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
// IE fix to hide scrollbars when table body is empty
|
||||
$('tbody').filter(function (index) {
|
||||
return $(this).children().length < 1;
|
||||
}).remove();
|
||||
|
||||
// selectpicker
|
||||
$('select').selectpicker();
|
||||
|
||||
// haveibeenpwned?
|
||||
$('[data-hibp]').after('<p class="small haveibeenpwned">↪ Check against haveibeenpwned.com</p><span class="hibp-out"></span>');
|
||||
$('[data-hibp]').on('input', function() {
|
||||
out_field = $(this).next('.haveibeenpwned').next('.hibp-out').text('').attr('class', 'hibp-out');
|
||||
});
|
||||
$('.haveibeenpwned:not(.task-running)').on('click', function() {
|
||||
var hibp_field = $(this)
|
||||
$(hibp_field).addClass('task-running');
|
||||
var hibp_result = $(hibp_field).next('.hibp-out')
|
||||
var password_field = $(this).prev('[data-hibp]')
|
||||
if ($(password_field).val() == '') {
|
||||
shake(password_field);
|
||||
}
|
||||
else {
|
||||
$(hibp_result).attr('class', 'hibp-out label label-info');
|
||||
$(hibp_result).text(lang_footer.loading);
|
||||
var password_digest = $.sha1($(password_field).val())
|
||||
var digest_five = password_digest.substring(0, 5).toUpperCase();
|
||||
var queryURL = "https://api.pwnedpasswords.com/range/" + digest_five;
|
||||
var compl_digest = password_digest.substring(5, 41).toUpperCase();
|
||||
$.ajax({
|
||||
url: queryURL,
|
||||
type: 'GET',
|
||||
success: function(res) {
|
||||
if (res.search(compl_digest) > -1){
|
||||
$(hibp_result).removeClass('label label-info').addClass('label label-danger');
|
||||
$(hibp_result).text(lang_footer.hibp_nok)
|
||||
} else {
|
||||
$(hibp_result).removeClass('label label-info').addClass('label label-success');
|
||||
$(hibp_result).text(lang_footer.hibp_ok)
|
||||
}
|
||||
$(hibp_field).removeClass('task-running');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
$(hibp_result).removeClass('label label-info').addClass('label label-warning');
|
||||
$(hibp_result).text('API error: ' + xhr.responseText)
|
||||
$(hibp_field).removeClass('task-running');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Disable disallowed inputs
|
||||
$('[data-acl="0"]').each(function(){
|
||||
if ($(this).attr('class') == 'btn-group') {
|
||||
$(this).find('a').each(function(){
|
||||
$(this).removeClass('dropdown-toggle')
|
||||
.removeAttr('data-toggle')
|
||||
.removeAttr('id')
|
||||
.attr("disabled", true);
|
||||
$(this).click(function(event) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
});
|
||||
});
|
||||
$(this).find('button').each(function() {
|
||||
$(this).attr("disabled", true);
|
||||
});
|
||||
} else if ($(this).attr('class') == 'input-group') {
|
||||
$(this).find('input').each(function() {
|
||||
$(this).removeClass('dropdown-toggle')
|
||||
.removeAttr('data-toggle')
|
||||
.attr("disabled", true);
|
||||
$(this).click(function(event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
});
|
||||
$(this).find('button').each(function() {
|
||||
$(this).attr("disabled", true);
|
||||
});
|
||||
} else if ($(this).hasClass('btn')) {
|
||||
$(this).attr("disabled", true);
|
||||
} else if ($(this).attr('data-provide', 'slider')) {
|
||||
$(this).slider("disable");
|
||||
}
|
||||
$(this).data("toggle", "tooltip");
|
||||
$(this).attr("title", lang_acl.prohibited);
|
||||
$(this).tooltip();
|
||||
});
|
||||
|
||||
// disable submit after submitting form (not API driven buttons)
|
||||
$('form').submit(function() {
|
||||
if ($('form button[type="submit"]').data('submitted') == '1') {
|
||||
return false;
|
||||
} else {
|
||||
$(this).find('button[type="submit"]').first().text(lang_footer.loading);
|
||||
$('form button[type="submit"]').attr('data-submitted', '1');
|
||||
function disableF5(e) { if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) e.preventDefault(); };
|
||||
$(document).on("keydown", disableF5);
|
||||
}
|
||||
});
|
||||
|
||||
// trigger container restart
|
||||
$('#RestartContainer').on('show.bs.modal', function(e) {
|
||||
var container = $(e.relatedTarget).data('container');
|
||||
$('#containerName').text(container);
|
||||
$('#triggerRestartContainer').click(function(){
|
||||
$(this).prop("disabled",true);
|
||||
$(this).html('<span class="glyphicon glyphicon-refresh glyphicon-spin"></span> ');
|
||||
$('#statusTriggerRestartContainer').html(lang_footer.restarting_container);
|
||||
$.ajax({
|
||||
method: 'get',
|
||||
url: '/inc/ajax/container_ctrl.php',
|
||||
timeout: docker_timeout,
|
||||
data: {
|
||||
'service': container,
|
||||
'action': 'restart'
|
||||
}
|
||||
})
|
||||
.always( function (data, status) {
|
||||
$('#statusTriggerRestartContainer').append(data);
|
||||
var htmlResponse = $.parseHTML(data)
|
||||
if ($(htmlResponse).find('span').hasClass('text-success')) {
|
||||
$('#triggerRestartContainer').html('<span class="glyphicon glyphicon-ok"></span> ');
|
||||
setTimeout(function(){
|
||||
$('#RestartContainer').modal('toggle');
|
||||
window.location = window.location.href.split("#")[0];
|
||||
}, 1200);
|
||||
} else {
|
||||
$('#triggerRestartContainer').html('<span class="glyphicon glyphicon-remove"></span> ');
|
||||
}
|
||||
})
|
||||
});
|
||||
})
|
||||
});
|
|
@ -0,0 +1 @@
|
|||
!function(r){var o=function(r,o){return r<<o|r>>>32-o},e=function(r){var o,e="";for(o=7;o>=0;o--)e+=(r>>>4*o&15).toString(16);return e};jQuery.extend({sha1:function(r){var a,t,n,h,C,c,f,d,u,i=new Array(80),A=1732584193,g=4023233417,s=2562383102,S=271733878,m=3285377520,p=(r=function(r){r=r.replace(/\x0d\x0a/g,"\n");for(var o="",e=0;e<r.length;e++){var a=r.charCodeAt(e);a<128?o+=String.fromCharCode(a):a>127&&a<2048?(o+=String.fromCharCode(a>>6|192),o+=String.fromCharCode(63&a|128)):(o+=String.fromCharCode(a>>12|224),o+=String.fromCharCode(a>>6&63|128),o+=String.fromCharCode(63&a|128))}return o}(r)).length,l=new Array;for(t=0;t<p-3;t+=4)n=r.charCodeAt(t)<<24|r.charCodeAt(t+1)<<16|r.charCodeAt(t+2)<<8|r.charCodeAt(t+3),l.push(n);switch(p%4){case 0:t=2147483648;break;case 1:t=r.charCodeAt(p-1)<<24|8388608;break;case 2:t=r.charCodeAt(p-2)<<24|r.charCodeAt(p-1)<<16|32768;break;case 3:t=r.charCodeAt(p-3)<<24|r.charCodeAt(p-2)<<16|r.charCodeAt(p-1)<<8|128}for(l.push(t);l.length%16!=14;)l.push(0);for(l.push(p>>>29),l.push(p<<3&4294967295),a=0;a<l.length;a+=16){for(t=0;t<16;t++)i[t]=l[a+t];for(t=16;t<=79;t++)i[t]=o(i[t-3]^i[t-8]^i[t-14]^i[t-16],1);for(h=A,C=g,c=s,f=S,d=m,t=0;t<=19;t++)u=o(h,5)+(C&c|~C&f)+d+i[t]+1518500249&4294967295,d=f,f=c,c=o(C,30),C=h,h=u;for(t=20;t<=39;t++)u=o(h,5)+(C^c^f)+d+i[t]+1859775393&4294967295,d=f,f=c,c=o(C,30),C=h,h=u;for(t=40;t<=59;t++)u=o(h,5)+(C&c|C&f|c&f)+d+i[t]+2400959708&4294967295,d=f,f=c,c=o(C,30),C=h,h=u;for(t=60;t<=79;t++)u=o(h,5)+(C^c^f)+d+i[t]+3395469782&4294967295,d=f,f=c,c=o(C,30),C=h,h=u;A=A+h&4294967295,g=g+C&4294967295,s=s+c&4294967295,S=S+f&4294967295,m=m+d&4294967295}return(u=e(A)+e(g)+e(s)+e(S)+e(m)).toLowerCase()}})}();
|
|
@ -1039,6 +1039,12 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
|
|||
case "rl-mbox":
|
||||
process_edit_return(ratelimit('edit', 'mailbox', array_merge(array('object' => $items), $attr)));
|
||||
break;
|
||||
case "user-acl":
|
||||
process_edit_return(acl('edit', 'user', array_merge(array('username' => $items), $attr)));
|
||||
break;
|
||||
case "da-acl":
|
||||
process_edit_return(acl('edit', 'domainadmin', array_merge(array('username' => $items), $attr)));
|
||||
break;
|
||||
case "alias-domain":
|
||||
process_edit_return(mailbox('edit', 'alias_domain', array_merge(array('alias_domain' => $items), $attr)));
|
||||
break;
|
||||
|
|
|
@ -16,6 +16,9 @@ $lang['footer']['delete_these_items'] = 'Sind Sie sicher, dass die Änderungen a
|
|||
$lang['footer']['delete_now'] = 'Jetzt löschen';
|
||||
$lang['footer']['cancel'] = 'Abbrechen';
|
||||
|
||||
$lang['footer']['hibp_nok'] = 'Übereinstimmung gefunden! Dieses Passwort ist potentiell gefährlich!';
|
||||
$lang['footer']['hibp_ok'] = 'Keine Übereinstimmung gefunden.';
|
||||
|
||||
$lang['danger']['mysql_error'] = "MySQL Fehler: %s";
|
||||
$lang['danger']['redis_error'] = "Redis Fehler: %s";
|
||||
$lang['danger']['unknown_tfa_method'] = "Unbekannte TFA Methode";
|
||||
|
@ -43,6 +46,7 @@ $lang['danger']['domain_cannot_match_hostname'] = "Domain darf nicht dem Hostnam
|
|||
$lang['warning']['domain_added_sogo_failed'] = "Domain wurde hinzugefügt; SOGo konnte nicht neugestartet werden";
|
||||
$lang['danger']['rl_timeframe'] = "Ratelimit Zeitraum ist inkorrekt";
|
||||
$lang['success']['rl_saved'] = "Ratelimit für Objekt %s wurde gesetzt";
|
||||
$lang['success']['acl_saved'] = "ACL für Objekt %s wurde gesetzt";
|
||||
$lang['success']['deleted_syncjobs'] = "Syncjobs gelöscht: %s";
|
||||
$lang['success']['deleted_syncjob'] = "Syncjobs ID %s gelöscht";
|
||||
$lang['success']['delete_filters'] = "Filter gelöscht: %s";
|
||||
|
@ -332,6 +336,8 @@ $lang['edit']['relay_all_info'] = '<small>Wenn Sie <b>nicht</b> alle Empfänger-
|
|||
$lang['edit']['full_name'] = 'Voller Name';
|
||||
$lang['edit']['quota_mb'] = 'Speicherplatz (MiB)';
|
||||
$lang['edit']['sender_acl'] = 'Darf Nachrichten versenden als';
|
||||
$lang['edit']['sender_acl_disabled'] = '↳ <span class="label label-danger">Absenderprüfung deaktiviert</span>';
|
||||
$lang['user']['sender_acl_disabled'] = '<span class="label label-danger">Absenderprüfung deaktiviert</span>';
|
||||
$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 u. Alias-Dom. nicht prüfen';
|
||||
|
@ -339,7 +345,22 @@ $lang['edit']['multiple_bookings'] = 'Mehrfaches Buchen';
|
|||
$lang['edit']['kind'] = 'Art';
|
||||
$lang['edit']['resource'] = 'Ressource';
|
||||
|
||||
$lang['add']['syncjob'] = 'Sync-Job erstellen';
|
||||
$lang['acl']['spam_alias'] = 'Temporäre E-Mail Aliasse';
|
||||
$lang['acl']['tls_policy'] = 'Verschlüsselungsrichtlinie';
|
||||
$lang['acl']['spam_score'] = 'Spam Bewertung';
|
||||
$lang['acl']['spam_policy'] = 'Blacklist/Whitelist';
|
||||
$lang['acl']['delimiter_action'] = 'Delimiter Aktionen (tags)';
|
||||
$lang['acl']['syncjobs'] = 'Sync Jobs';
|
||||
$lang['acl']['eas_reset'] = 'EAS-Cache zurücksetzen';
|
||||
$lang['acl']['quarantine'] = 'Quarantäne';
|
||||
$lang['acl']['login_as'] = 'Einloggen als Mailbox-Benutzer';
|
||||
$lang['acl']['bcc_maps'] = 'BCC Maps';
|
||||
$lang['acl']['filters'] = 'Filter';
|
||||
$lang['acl']['ratelimit'] = 'Rate limit';
|
||||
$lang['acl']['recipient_maps'] = 'Empfängerumschreibungen';
|
||||
$lang['acl']['prohibited'] = 'Untersagt durch Richtlinie';
|
||||
|
||||
$lang['add']['generate'] = 'generieren';
|
||||
$lang['add']['syncjob_hint'] = 'Passwörter werden unverschlüsselt abgelegt!';
|
||||
$lang['add']['hostname'] = 'Servername';
|
||||
$lang['add']['port'] = 'Port';
|
||||
|
|
|
@ -16,6 +16,9 @@ $lang['footer']['delete_these_items'] = 'Please confirm your changes to the foll
|
|||
$lang['footer']['delete_now'] = 'Delete now';
|
||||
$lang['footer']['cancel'] = 'Cancel';
|
||||
|
||||
$lang['footer']['hibp_nok'] = 'Matched! This is a potentially dangerous password!';
|
||||
$lang['footer']['hibp_ok'] = 'No match found.';
|
||||
|
||||
$lang['danger']['mysql_error'] = "MySQL error: %s";
|
||||
$lang['danger']['redis_error'] = "Redis error: %s";
|
||||
$lang['danger']['unknown_tfa_method'] = "Unknown TFA method";
|
||||
|
@ -43,6 +46,7 @@ $lang['danger']['domain_cannot_match_hostname'] = "Domain cannot match hostname"
|
|||
$lang['warning']['domain_added_sogo_failed'] = "Added domain but failed to restart SOGo, please check your server logs.";
|
||||
$lang['danger']['rl_timeframe'] = "Rate limit time frame is incorrect";
|
||||
$lang['success']['rl_saved'] = "Rate limit for object %s saved";
|
||||
$lang['success']['acl_saved'] = "ACL for object %s saved";
|
||||
$lang['success']['deleted_syncjobs'] = "Deleted syncjobs: %s";
|
||||
$lang['success']['deleted_syncjob'] = "Deleted syncjob ID %s";
|
||||
$lang['success']['delete_filters'] = "Deleted filters: %s";
|
||||
|
@ -342,6 +346,7 @@ $lang['edit']['full_name'] = 'Full name';
|
|||
$lang['edit']['quota_mb'] = 'Quota (MiB)';
|
||||
$lang['edit']['sender_acl'] = 'Allow to send as';
|
||||
$lang['edit']['sender_acl_disabled'] = '↳ <span class="label label-danger">Sender check is disabled</span>';
|
||||
$lang['user']['sender_acl_disabled'] = '<span class="label label-danger">Sender check is disabled</span>';
|
||||
$lang['edit']['previous'] = 'Previous page';
|
||||
$lang['edit']['unchanged_if_empty'] = 'If unchanged leave blank';
|
||||
$lang['edit']['dont_check_sender_acl'] = "Disable sender check for domain %s (+ alias domains)";
|
||||
|
@ -349,6 +354,22 @@ $lang['edit']['multiple_bookings'] = 'Multiple bookings';
|
|||
$lang['edit']['kind'] = 'Kind';
|
||||
$lang['edit']['resource'] = 'Resource';
|
||||
|
||||
$lang['acl']['spam_alias'] = 'Temporary aliases';
|
||||
$lang['acl']['tls_policy'] = 'TLS policy';
|
||||
$lang['acl']['spam_score'] = 'Spam score';
|
||||
$lang['acl']['spam_policy'] = 'Blacklist/Whitelist';
|
||||
$lang['acl']['delimiter_action'] = 'Delimiter action';
|
||||
$lang['acl']['syncjobs'] = 'Sync jobs';
|
||||
$lang['acl']['eas_reset'] = 'Reset EAS devices';
|
||||
$lang['acl']['quarantine'] = 'Quarantine';
|
||||
$lang['acl']['login_as'] = 'Login as mailbox user';
|
||||
$lang['acl']['bcc_maps'] = 'BCC maps';
|
||||
$lang['acl']['filters'] = 'Filters';
|
||||
$lang['acl']['ratelimit'] = 'Rate limit';
|
||||
$lang['acl']['recipient_maps'] = 'Recipient maps';
|
||||
$lang['acl']['prohibited'] = 'Prohibited by ACL';
|
||||
|
||||
$lang['add']['generate'] = 'generate';
|
||||
$lang['add']['syncjob'] = 'Add sync job';
|
||||
$lang['add']['syncjob_hint'] = 'Be aware that passwords need to be saved plain-text!';
|
||||
$lang['add']['hostname'] = 'Hostname';
|
||||
|
|
|
@ -214,7 +214,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
<table class="table table-striped" id="filter_table"></table>
|
||||
</div>
|
||||
<div class="mass-actions-mailbox">
|
||||
<div class="btn-group">
|
||||
<div class="btn-group" data-acl="<?=$_SESSION['acl']['filters'];?>">
|
||||
<a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="filter_item" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
|
||||
<a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['quick_actions'];?> <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
@ -245,7 +245,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
<table class="table table-striped" id="bcc_table"></table>
|
||||
</div>
|
||||
<div class="mass-actions-mailbox">
|
||||
<div class="btn-group">
|
||||
<div class="btn-group" data-acl="<?=$_SESSION['acl']['bcc_maps'];?>">
|
||||
<a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="bcc" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
|
||||
<a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['quick_actions'];?> <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
@ -261,7 +261,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel panel-default <?=($_SESSION['mailcow_cc_role'] == "admin") ?: 'hidden';?>">
|
||||
<div class="panel-heading">
|
||||
<?=$lang['mailbox']['recipient_maps'];?> <span class="badge badge-info table-lines"></span>
|
||||
<div class="btn-group pull-right">
|
||||
|
@ -272,12 +272,6 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
<div class="table-responsive">
|
||||
<table class="table table-striped" id="recipient_map_table"></table>
|
||||
</div>
|
||||
<?php
|
||||
if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "admin"))
|
||||
$display = 'block';
|
||||
else
|
||||
$display = 'none';
|
||||
?>
|
||||
<div class="mass-actions-mailbox" style="display: <?php echo $display; ?>">
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="recipient_map" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
|
||||
|
@ -304,9 +298,12 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/modals/mailbox.php';
|
|||
<?php
|
||||
$lang_mailbox = json_encode($lang['mailbox']);
|
||||
echo "var lang = ". $lang_mailbox . ";\n";
|
||||
echo "var acl = '". json_encode($_SESSION['acl']) . "';\n";
|
||||
echo "var csrf_token = '". $_SESSION['CSRF']['TOKEN'] . "';\n";
|
||||
$role = ($_SESSION['mailcow_cc_role'] == "admin") ? 'admin' : 'domainadmin';
|
||||
$is_dual = (!empty($_SESSION["dual-login"]["username"])) ? 'true' : 'false';
|
||||
echo "var role = '". $role . "';\n";
|
||||
echo "var is_dual = " . $is_dual . ";\n";
|
||||
echo "var pagination_size = '". $PAGINATION_SIZE . "';\n";
|
||||
?>
|
||||
</script>
|
||||
|
|
|
@ -67,7 +67,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
|
|||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="name"><?=$lang['admin']['admin_domains'];?>:</label>
|
||||
<div class="col-sm-10">
|
||||
<select title="<?=$lang['admin']['search_domain_da'];?>" style="width:100%" name="domains" size="5" multiple>
|
||||
<select title="<?=$lang['admin']['search_domain_da'];?>" class="full-width-select" name="domains" size="5" multiple>
|
||||
<?php
|
||||
foreach (mailbox('get', 'domains') as $domain) {
|
||||
echo "<option>".htmlspecialchars($domain)."</option>";
|
||||
|
@ -79,7 +79,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
|
|||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="password"><?=$lang['admin']['password'];?>:</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" name="password" id="password" placeholder="" required>
|
||||
<input type="password" class="form-control" data-hibp="true" name="password" id="password" placeholder="" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
|
|
@ -23,7 +23,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
|
|||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="domain"><?=$lang['add']['domain'];?>:</label>
|
||||
<div class="col-sm-10">
|
||||
<select data-live-search="true" id="addSelectDomain" name="domain" id="domain" required>
|
||||
<select class="full-width-select" data-live-search="true" id="addSelectDomain" name="domain" id="domain" required>
|
||||
<?php
|
||||
foreach (mailbox('get', 'domains') as $domain) {
|
||||
echo "<option>".htmlspecialchars($domain)."</option>";
|
||||
|
@ -48,10 +48,9 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="password"><?=$lang['add']['password'];?></label>
|
||||
<label class="control-label col-sm-2" for="password"><?=$lang['add']['password'];?> (<a href="#" class="generate_password"><?=$lang['add']['generate'];?></a>)</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" name="password" id="password" placeholder="" required>
|
||||
(<a href="#" class="generate_password">Generate</a>)
|
||||
<input type="password" data-hibp="true" class="form-control" name="password" id="password" placeholder="" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
|
|
@ -37,7 +37,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
|
|||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="password1"><?=$lang['add']['password'];?></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="password" class="form-control" name="password1" id="password1" required>
|
||||
<input type="password" class="form-control" name="password1" id="password1" data-hibp="true" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -155,7 +155,7 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
|
|||
<div class="form-group">
|
||||
<label class="control-label col-sm-3" for="user_new_pass"><?=$lang['user']['new_password'];?></label>
|
||||
<div class="col-sm-5">
|
||||
<input type="password" class="form-control" name="user_new_pass" id="user_new_pass" autocomplete="off" required>
|
||||
<input type="password" data-hibp="true" class="form-control" name="user_new_pass" id="user_new_pass" autocomplete="off" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
|
|
@ -18,7 +18,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
<table id="quarantinetable" class="table table-striped"></table>
|
||||
</div>
|
||||
<div class="mass-actions-quarantine">
|
||||
<div class="btn-group">
|
||||
<div class="btn-group" data-acl="<?=$_SESSION['acl']['quarantine'];?>">
|
||||
<a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="qitems" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['quarantine']['toggle_all'];?></a>
|
||||
<a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['quarantine']['quick_actions'];?> <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
|
|
@ -88,7 +88,6 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
fclose($fh);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="container">
|
||||
<h3><?=$lang['user']['user_settings'];?></h3>
|
||||
|
@ -145,7 +144,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
<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><?=$user_get_alias_details['aliases_also_send_as'];?></p>
|
||||
<p><?=($user_get_alias_details['aliases_also_send_as'] == '*') ? $lang['user']['sender_acl_disabled'] : $user_get_alias_details['aliases_also_send_as'];?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
@ -172,87 +171,71 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
<p><?=formatBytes($mailboxdata['quota_used'], 2);?> / <?=formatBytes($mailboxdata['quota'], 2);?>, <?=$mailboxdata['messages'];?> <?=$lang['user']['messages'];?></p>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<?php
|
||||
($_SESSION['acl']['delimiter_action'] == 0 && $_SESSION['acl']['delimiter_action'] == 0 && $_SESSION['acl']['delimiter_action'] == 0) ? null : '<hr>';
|
||||
// Show tagging options
|
||||
if ($_SESSION['acl']['delimiter_action'] == 1):
|
||||
$get_tagging_options = mailbox('get', 'delimiter_action', $username);
|
||||
?>
|
||||
<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">
|
||||
<div class="btn-group">
|
||||
|
||||
<div class="btn-group" data-acl="<?=$_SESSION['acl']['delimiter_action'];?>">
|
||||
<button type="button" class="btn btn-sm btn-default <?=($get_tagging_options == "subfolder") ? 'active' : null; ?>"
|
||||
id="edit_selected"
|
||||
data-item="<?= htmlentities($username); ?>"
|
||||
data-id="delimiter_action"
|
||||
data-api-url='edit/delimiter_action'
|
||||
data-api-attr='{"tagged_mail_handler":"subfolder"}'><?=$lang['user']['tag_in_subfolder'];?></button>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-default <?=($get_tagging_options == "subject") ? 'active' : null; ?>"
|
||||
id="edit_selected"
|
||||
data-item="<?= htmlentities($username); ?>"
|
||||
data-id="delimiter_action"
|
||||
data-api-url='edit/delimiter_action'
|
||||
data-api-attr='{"tagged_mail_handler":"subject"}'><?=$lang['user']['tag_in_subject'];?></button>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-default <?=($get_tagging_options == "none") ? 'active' : null; ?>"
|
||||
id="edit_selected"
|
||||
data-item="<?= htmlentities($username); ?>"
|
||||
data-id="delimiter_action"
|
||||
data-api-url='edit/delimiter_action'
|
||||
data-api-attr='{"tagged_mail_handler":"none"}'><?=$lang['user']['tag_in_none'];?></button>
|
||||
|
||||
</div>
|
||||
<p class="help-block"><?=$lang['user']['tag_help_explain'];?></p>
|
||||
<p class="help-block"><?=$lang['user']['tag_help_example'];?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
// Show TLS policy options
|
||||
if ($_SESSION['acl']['tls_policy'] == 1):
|
||||
$get_tls_policy = mailbox('get', 'tls_policy', $username);
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-xs-5 text-right"><?=$lang['user']['tls_policy'];?>:</div>
|
||||
<div class="col-md-9 col-xs-7">
|
||||
<div class="btn-group">
|
||||
|
||||
<div class="btn-group" data-acl="<?=$_SESSION['acl']['tls_policy'];?>">
|
||||
<button type="button" class="btn btn-sm btn-default <?=($get_tls_policy['tls_enforce_in'] == "1") ? "active" : null;?>"
|
||||
id="edit_selected"
|
||||
data-item="<?= htmlentities($username); ?>"
|
||||
data-id="tls_policy"
|
||||
data-api-url='edit/tls_policy'
|
||||
data-api-attr='{"tls_enforce_in":<?=($get_tls_policy['tls_enforce_in'] == "1") ? "0" : "1";?>}'><?=$lang['user']['tls_enforce_in'];?></button>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-default <?=($get_tls_policy['tls_enforce_out'] == "1") ? "active" : null;?>"
|
||||
id="edit_selected"
|
||||
data-item="<?= htmlentities($username); ?>"
|
||||
data-id="tls_policy"
|
||||
data-api-url='edit/tls_policy'
|
||||
data-api-attr='{"tls_enforce_out":<?=($get_tls_policy['tls_enforce_out'] == "1") ? "0" : "1";?>}'><?=$lang['user']['tls_enforce_out'];?></button>
|
||||
|
||||
</div>
|
||||
<p class="help-block"><?=$lang['user']['tls_policy_warning'];?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
// Rest EAS devices
|
||||
if ($_SESSION['acl']['eas_reset'] == 1):
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-xs-5 text-right"><?=$lang['user']['eas_reset'];?>:</div>
|
||||
<div class="col-md-9 col-xs-7">
|
||||
<button class="btn btn-xs btn-default" id="delete_selected" data-text="<?=$lang['user']['eas_reset'];?>?" data-item="<?= htmlentities($username); ?>" data-id="eas_cache" data-api-url='delete/eas_cache' href="#"><?=$lang['user']['eas_reset_now'];?></button>
|
||||
<button class="btn btn-xs btn-default" data-acl="<?=$_SESSION['acl']['eas_reset'];?>" id="delete_selected" data-text="<?=$lang['user']['eas_reset'];?>?" data-item="<?= htmlentities($username); ?>" data-id="eas_cache" data-api-url='delete/eas_cache' href="#"><?=$lang['user']['eas_reset_now'];?></button>
|
||||
<p class="help-block"><?=$lang['user']['eas_reset_help'];?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -273,11 +256,9 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if ($_SESSION['acl']['spam_alias'] == 1):
|
||||
?>
|
||||
|
||||
<div class="mass-actions-user">
|
||||
<div class="btn-group">
|
||||
<div class="btn-group" data-acl="<?=$_SESSION['acl']['spam_alias'];?>">
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="tla" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
|
||||
<a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['quick_actions'];?> <span class="caret"></span></a>
|
||||
|
@ -299,9 +280,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
|
||||
</div>
|
||||
|
||||
<div role="tabpanel" class="tab-pane" id="Spamfilter">
|
||||
|
@ -309,7 +288,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
<form class="form-horizontal" role="form" data-id="spam_score" method="post">
|
||||
<div class="form-group">
|
||||
<div class="col-lg-6 col-sm-12">
|
||||
<input name="spam_score" id="spam_score" type="text" style="width: 100%;"
|
||||
<input data-acl="<?=$_SESSION['acl']['spam_score'];?>" name="spam_score" id="spam_score" type="text" style="width: 100%;"
|
||||
data-provide="slider"
|
||||
data-slider-min="1"
|
||||
data-slider-max="2000"
|
||||
|
@ -330,21 +309,17 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
<p><?=$lang['user']['spamfilter_hint'];?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if ($_SESSION['acl']['spam_score'] == 1):
|
||||
?>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-10">
|
||||
<button type="button" class="btn btn-sm btn-success" id="edit_selected"
|
||||
<button data-acl="<?=$_SESSION['acl']['spam_score'];?>" type="button" class="btn btn-sm btn-success" id="edit_selected"
|
||||
data-item="<?= htmlentities($username); ?>"
|
||||
data-id="spam_score"
|
||||
data-api-url='edit/spam-score'
|
||||
data-api-attr='{}'><?=$lang['user']['save_changes'];?></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
|
||||
</form>
|
||||
<hr>
|
||||
<div class="row">
|
||||
|
@ -354,26 +329,22 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
<div class="table-responsive">
|
||||
<table class="table table-striped table-condensed" id="wl_policy_mailbox_table"></table>
|
||||
</div>
|
||||
<?php
|
||||
if ($_SESSION['acl']['spam_policy'] == 1):
|
||||
?>
|
||||
|
||||
<div class="mass-actions-user">
|
||||
<div class="btn-group">
|
||||
<div class="btn-group" data-acl="<?=$_SESSION['acl']['spam_policy'];?>">
|
||||
<a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="policy_wl_mailbox" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
|
||||
<a class="btn btn-sm btn-danger" id="delete_selected" data-id="policy_wl_mailbox" data-api-url='delete/mailbox-policy' href="#"><?=$lang['mailbox']['remove'];?></a></li>
|
||||
</div>
|
||||
</div>
|
||||
<form class="form-inline" data-id="add_wl_policy_mailbox">
|
||||
<div class="input-group">
|
||||
<div class="input-group" data-acl="<?=$_SESSION['acl']['spam_policy'];?>">
|
||||
<input type="text" class="form-control" name="object_from" id="object_from" placeholder="*@example.org" required>
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" id="add_item" data-id="add_wl_policy_mailbox" data-api-url='add/mailbox-policy' data-api-attr='{"username":<?= json_encode($username); ?>,"object_list":"wl"}' href="#"><span class="glyphicon glyphicon-plus"></span> <?=$lang['user']['spamfilter_table_add'];?></button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<h4><?=$lang['user']['spamfilter_bl'];?></h4>
|
||||
|
@ -381,28 +352,22 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
<div class="table-responsive">
|
||||
<table class="table table-striped table-condensed" id="bl_policy_mailbox_table"></table>
|
||||
</div>
|
||||
<?php
|
||||
if ($_SESSION['acl']['spam_policy'] == 1):
|
||||
?>
|
||||
|
||||
<div class="mass-actions-user">
|
||||
<div class="btn-group">
|
||||
<div class="btn-group" data-acl="<?=$_SESSION['acl']['spam_policy'];?>">
|
||||
<a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="policy_bl_mailbox" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
|
||||
<a class="btn btn-sm btn-danger" id="delete_selected" data-id="policy_bl_mailbox" data-api-url='delete/mailbox-policy' href="#"><?=$lang['mailbox']['remove'];?></a></li>
|
||||
</div>
|
||||
</div>
|
||||
<form class="form-inline" data-id="add_bl_policy_mailbox">
|
||||
<div class="input-group">
|
||||
<div class="input-group" data-acl="<?=$_SESSION['acl']['spam_policy'];?>">
|
||||
<input type="text" class="form-control" name="object_from" id="object_from" placeholder="*@example.org" required>
|
||||
<input type="hidden" name="username" value="<?= htmlentities($username) ;?>">
|
||||
<input type="hidden" name="object_list" value="bl">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" id="add_item" data-id="add_bl_policy_mailbox" data-api-url='add/mailbox-policy' data-api-attr='{"username":<?= json_encode($username); ?>,"object_list":"bl"}' href="#"><span class="glyphicon glyphicon-plus"></span> <?=$lang['user']['spamfilter_table_add'];?></button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -411,11 +376,9 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
<div class="table-responsive">
|
||||
<table class="table table-striped" id="sync_job_table"></table>
|
||||
</div>
|
||||
<?php
|
||||
if ($_SESSION['acl']['syncjobs'] == 1):
|
||||
?>
|
||||
|
||||
<div class="mass-actions-user">
|
||||
<div class="btn-group">
|
||||
<div class="btn-group" data-acl="<?=$_SESSION['acl']['syncjobs'];?>">
|
||||
<a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="syncjob" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
|
||||
<a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['quick_actions'];?> <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
|
@ -427,9 +390,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
<a class="btn btn-sm btn-success" href="#" data-toggle="modal" data-target="#addSyncJobModal"><span class="glyphicon glyphicon-plus"></span> <?=$lang['user']['create_syncjob'];?></a>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -330,7 +330,7 @@ services:
|
|||
- /lib/modules:/lib/modules:ro
|
||||
|
||||
watchdog-mailcow:
|
||||
image: mailcow/watchdog:1.19
|
||||
image: mailcow/watchdog:1.21
|
||||
# Debug
|
||||
#command: /watchdog.sh
|
||||
build: ./data/Dockerfiles/watchdog
|
||||
|
|
Loading…
Reference in New Issue