mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-10-22 09:13:26 +00:00
Merge branch 'master' into admin-login
This commit is contained in:
20 files changed
+154
-63
No files matched your search
@@ -5,6 +5,16 @@ exec 5>&1
|
|||||||
# Thanks to https://github.com/cvmiller -> https://github.com/cvmiller/expand6
|
# Thanks to https://github.com/cvmiller -> https://github.com/cvmiller/expand6
|
||||||
source /srv/expand6.sh
|
source /srv/expand6.sh
|
||||||
|
|
||||||
|
# Skipping IP check when we like to live dangerously
|
||||||
|
if [[ "${SKIP_IP_CHECK}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
||||||
|
SKIP_IP_CHECK=y
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Skipping HTTP check when we like to live dangerously
|
||||||
|
if [[ "${SKIP_HTTP_VERIFICATION}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
||||||
|
SKIP_HTTP_VERIFICATION=y
|
||||||
|
fi
|
||||||
|
|
||||||
log_f() {
|
log_f() {
|
||||||
if [[ ${2} == "no_nl" ]]; then
|
if [[ ${2} == "no_nl" ]]; then
|
||||||
echo -n "$(date) - ${1}"
|
echo -n "$(date) - ${1}"
|
||||||
@@ -120,7 +130,10 @@ verify_challenge_path(){
|
|||||||
# verify_challenge_path URL 4|6
|
# verify_challenge_path URL 4|6
|
||||||
RAND_FILE=${RANDOM}${RANDOM}${RANDOM}
|
RAND_FILE=${RANDOM}${RANDOM}${RANDOM}
|
||||||
touch /var/www/acme/${RAND_FILE}
|
touch /var/www/acme/${RAND_FILE}
|
||||||
if [[ "$(curl -${2} http://${1}/.well-known/acme-challenge/${RAND_FILE} --write-out %{http_code} --silent --output /dev/null)" =~ ^(2|3) ]]; then
|
if [[ ${SKIP_HTTP_VERIFICATION} == "y" ]]; then
|
||||||
|
echo '(skipping check, returning 0)'
|
||||||
|
return 0
|
||||||
|
elif [[ "$(curl -${2} http://${1}/.well-known/acme-challenge/${RAND_FILE} --write-out %{http_code} --silent --output /dev/null)" =~ ^(2|3) ]]; then
|
||||||
rm /var/www/acme/${RAND_FILE}
|
rm /var/www/acme/${RAND_FILE}
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
@@ -199,11 +212,6 @@ while true; do
|
|||||||
chmod 600 ${ACME_BASE}/acme/key.pem
|
chmod 600 ${ACME_BASE}/acme/key.pem
|
||||||
chmod 600 ${ACME_BASE}/acme/account.pem
|
chmod 600 ${ACME_BASE}/acme/account.pem
|
||||||
|
|
||||||
# Skipping IP check when we like to live dangerously
|
|
||||||
if [[ "${SKIP_IP_CHECK}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
|
||||||
SKIP_IP_CHECK=y
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Cleaning up and init validation arrays
|
# Cleaning up and init validation arrays
|
||||||
unset SQL_DOMAIN_ARR
|
unset SQL_DOMAIN_ARR
|
||||||
unset VALIDATED_CONFIG_DOMAINS
|
unset VALIDATED_CONFIG_DOMAINS
|
||||||
@@ -479,6 +487,7 @@ while true; do
|
|||||||
ACME_RESPONSE_B64=$(echo "${ACME_RESPONSE}" | openssl enc -e -A -base64)
|
ACME_RESPONSE_B64=$(echo "${ACME_RESPONSE}" | openssl enc -e -A -base64)
|
||||||
log_f "${ACME_RESPONSE_B64}" redis_only b64
|
log_f "${ACME_RESPONSE_B64}" redis_only b64
|
||||||
log_f "Retrying in 30 minutes..."
|
log_f "Retrying in 30 minutes..."
|
||||||
|
redis-cli -h redis SET ACME_FAIL_TIME "$(date +%s)"
|
||||||
sleep 30m
|
sleep 30m
|
||||||
exec $(readlink -f "$0")
|
exec $(readlink -f "$0")
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
gettext \
|
gettext \
|
||||||
gnupg \
|
gnupg \
|
||||||
mysql-client \
|
mysql-client \
|
||||||
|
rsync \
|
||||||
supervisor \
|
supervisor \
|
||||||
syslog-ng \
|
syslog-ng \
|
||||||
syslog-ng-core \
|
syslog-ng-core \
|
||||||
@@ -52,6 +53,4 @@ RUN chmod +x /bootstrap-sogo.sh \
|
|||||||
|
|
||||||
CMD exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
|
CMD exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
|
||||||
|
|
||||||
VOLUME /usr/lib/GNUstep/SOGo/
|
|
||||||
|
|
||||||
RUN rm -rf /tmp/* /var/tmp/*
|
RUN rm -rf /tmp/* /var/tmp/*
|
||||||
@@ -196,4 +196,8 @@ fi
|
|||||||
# Copy logo, if any
|
# Copy logo, if any
|
||||||
[[ -f /etc/sogo/sogo-full.svg ]] && cp /etc/sogo/sogo-full.svg /usr/lib/GNUstep/SOGo/WebServerResources/img/sogo-full.svg
|
[[ -f /etc/sogo/sogo-full.svg ]] && cp /etc/sogo/sogo-full.svg /usr/lib/GNUstep/SOGo/WebServerResources/img/sogo-full.svg
|
||||||
|
|
||||||
|
# Rsync web content
|
||||||
|
echo "Syncing web content with named volume"
|
||||||
|
rsync -a /usr/lib/GNUstep/SOGo/. /sogo_web/
|
||||||
|
|
||||||
exec gosu sogo /usr/sbin/sogod
|
exec gosu sogo /usr/sbin/sogod
|
||||||
@@ -5,6 +5,8 @@ trap "kill 0" EXIT
|
|||||||
|
|
||||||
# Prepare
|
# Prepare
|
||||||
BACKGROUND_TASKS=()
|
BACKGROUND_TASKS=()
|
||||||
|
echo "Waiting for containers to settle..."
|
||||||
|
sleep 10
|
||||||
|
|
||||||
if [[ "${USE_WATCHDOG}" =~ ^([nN][oO]|[nN])+$ ]]; then
|
if [[ "${USE_WATCHDOG}" =~ ^([nN][oO]|[nN])+$ ]]; then
|
||||||
echo -e "$(date) - USE_WATCHDOG=n, skipping watchdog..."
|
echo -e "$(date) - USE_WATCHDOG=n, skipping watchdog..."
|
||||||
@@ -350,6 +352,38 @@ ratelimit_checks() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
acme_checks() {
|
||||||
|
err_count=0
|
||||||
|
diff_c=0
|
||||||
|
THRESHOLD=1
|
||||||
|
ACME_LOG_STATUS=$(redis-cli -h redis GET ACME_FAIL_TIME)
|
||||||
|
if [[ -z "${ACME_LOG_STATUS}" ]]; then
|
||||||
|
redis-cli -h redis SET ACME_FAIL_TIME 0
|
||||||
|
ACME_LOG_STATUS=0
|
||||||
|
fi
|
||||||
|
# Reduce error count by 2 after restarting an unhealthy container
|
||||||
|
trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1
|
||||||
|
while [ ${err_count} -lt ${THRESHOLD} ]; do
|
||||||
|
err_c_cur=${err_count}
|
||||||
|
ACME_LOG_STATUS_PREV=${ACME_LOG_STATUS}
|
||||||
|
ACME_LOG_STATUS=$(redis-cli -h redis GET ACME_FAIL_TIME)
|
||||||
|
if [[ ${ACME_LOG_STATUS_PREV} != ${ACME_LOG_STATUS} ]]; then
|
||||||
|
err_count=$(( ${err_count} + 1 ))
|
||||||
|
fi
|
||||||
|
[ ${err_c_cur} -eq ${err_count} ] && [ ! $((${err_count} - 1)) -lt 0 ] && err_count=$((${err_count} - 1)) diff_c=1
|
||||||
|
[ ${err_c_cur} -ne ${err_count} ] && diff_c=$(( ${err_c_cur} - ${err_count} ))
|
||||||
|
progress "ACME" ${THRESHOLD} $(( ${THRESHOLD} - ${err_count} )) ${diff_c}
|
||||||
|
if [[ $? == 10 ]]; then
|
||||||
|
diff_c=0
|
||||||
|
sleep 1
|
||||||
|
else
|
||||||
|
diff_c=0
|
||||||
|
sleep $(( ( RANDOM % 30 ) + 10 ))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
ipv6nat_checks() {
|
ipv6nat_checks() {
|
||||||
err_count=0
|
err_count=0
|
||||||
diff_c=0
|
diff_c=0
|
||||||
@@ -518,6 +552,16 @@ done
|
|||||||
) &
|
) &
|
||||||
BACKGROUND_TASKS+=($!)
|
BACKGROUND_TASKS+=($!)
|
||||||
|
|
||||||
|
(
|
||||||
|
while true; do
|
||||||
|
if ! acme_checks; then
|
||||||
|
log_msg "ACME client hit error limit"
|
||||||
|
echo acme-tiny > /tmp/com_pipe
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
) &
|
||||||
|
BACKGROUND_TASKS+=($!)
|
||||||
|
|
||||||
(
|
(
|
||||||
while true; do
|
while true; do
|
||||||
if ! ipv6nat_checks; then
|
if ! ipv6nat_checks; then
|
||||||
@@ -567,7 +611,10 @@ while true; do
|
|||||||
fi
|
fi
|
||||||
if [[ ${com_pipe_answer} == "ratelimit" ]]; then
|
if [[ ${com_pipe_answer} == "ratelimit" ]]; then
|
||||||
log_msg "At least one ratelimit was applied"
|
log_msg "At least one ratelimit was applied"
|
||||||
[[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${com_pipe_answer}" "No further information available."
|
[[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${com_pipe_answer}" "Please see mailcow UI logs for further information."
|
||||||
|
elif [[ ${com_pipe_answer} == "acme-tiny" ]]; then
|
||||||
|
log_msg "acme-tiny client returned non-zero exit code"
|
||||||
|
[[ ! -z ${WATCHDOG_NOTIFY_EMAIL} ]] && mail_error "${com_pipe_answer}" "Please check acme-mailcow for ruther information."
|
||||||
elif [[ ${com_pipe_answer} =~ .+-mailcow ]] || [[ ${com_pipe_answer} == "ipv6nat-mailcow" ]]; then
|
elif [[ ${com_pipe_answer} =~ .+-mailcow ]] || [[ ${com_pipe_answer} == "ipv6nat-mailcow" ]]; then
|
||||||
kill -STOP ${BACKGROUND_TASKS[*]}
|
kill -STOP ${BACKGROUND_TASKS[*]}
|
||||||
sleep 3
|
sleep 3
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
/*! =======================================================
|
/*! =======================================================
|
||||||
VERSION 10.6.0
|
VERSION 10.6.1
|
||||||
========================================================= */
|
========================================================= */
|
||||||
/*! =========================================================
|
/*! =========================================================
|
||||||
* bootstrap-slider.js
|
* bootstrap-slider.js
|
||||||
|
|||||||
+2
-1
@@ -521,7 +521,8 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||||||
<br /><span id="quotaBadge" class="badge">max. <?=intval($result['max_new_quota'] / 1048576)?> MiB</span>
|
<br /><span id="quotaBadge" class="badge">max. <?=intval($result['max_new_quota'] / 1048576)?> MiB</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="number" name="quota" style="width:100%" min="1" max="<?=intval($result['max_new_quota'] / 1048576);?>" value="<?=intval($result['quota']) / 1048576;?>" class="form-control">
|
<input type="number" name="quota" style="width:100%" min="0" max="<?=intval($result['max_new_quota'] / 1048576);?>" value="<?=intval($result['quota']) / 1048576;?>" class="form-control">
|
||||||
|
<small class="help-block">0 = ∞</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ $(window).load(function() {
|
|||||||
$(".overlay").hide();
|
$(".overlay").hide();
|
||||||
});
|
});
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
$(document).on('shown.bs.modal', function(e) {
|
||||||
|
modal_id = $(e.relatedTarget).data('target');
|
||||||
|
$(modal_id).attr("aria-hidden","false");
|
||||||
|
});
|
||||||
// TFA, CSRF, Alerts in footer.inc.php
|
// TFA, CSRF, Alerts in footer.inc.php
|
||||||
// Other general functions in mailcow.js
|
// Other general functions in mailcow.js
|
||||||
<?php
|
<?php
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
function isset_has_content($var) {
|
||||||
|
if (isset($var) && $var != "") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
function hash_password($password) {
|
function hash_password($password) {
|
||||||
$salt_str = bin2hex(openssl_random_pseudo_bytes(8));
|
$salt_str = bin2hex(openssl_random_pseudo_bytes(8));
|
||||||
return "{SSHA256}".base64_encode(hash('sha256', $password . $salt_str, true) . $salt_str);
|
return "{SSHA256}".base64_encode(hash('sha256', $password . $salt_str, true) . $salt_str);
|
||||||
|
|||||||
@@ -756,7 +756,15 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
$password = $_data['password'];
|
$password = $_data['password'];
|
||||||
$password2 = $_data['password2'];
|
$password2 = $_data['password2'];
|
||||||
$name = ltrim(rtrim($_data['name'], '>'), '<');
|
$name = ltrim(rtrim($_data['name'], '>'), '<');
|
||||||
$quota_m = filter_var($_data['quota'], FILTER_SANITIZE_NUMBER_FLOAT);
|
$quota_m = intval($_data['quota']);
|
||||||
|
if ((!isset($_SESSION['acl']['unlimited_quota']) || $_SESSION['acl']['quarantine_notification'] != "1") && $quota_m === 0) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => 'unlimited_quota_acl'
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (empty($name)) {
|
if (empty($name)) {
|
||||||
$name = $local_part;
|
$name = $local_part;
|
||||||
}
|
}
|
||||||
@@ -844,14 +852,6 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!is_numeric($quota_m) || $quota_m == "0") {
|
|
||||||
$_SESSION['return'][] = array(
|
|
||||||
'type' => 'danger',
|
|
||||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
|
||||||
'msg' => 'quota_not_0_not_numeric'
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!empty($password) && !empty($password2)) {
|
if (!empty($password) && !empty($password2)) {
|
||||||
if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
|
if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
@@ -1993,9 +1993,9 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
$active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int'];
|
$active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int'];
|
||||||
(int)$force_pw_update = (isset($_data['force_pw_update'])) ? intval($_data['force_pw_update']) : intval($is_now['attributes']['force_pw_update']);
|
(int)$force_pw_update = (isset($_data['force_pw_update'])) ? intval($_data['force_pw_update']) : intval($is_now['attributes']['force_pw_update']);
|
||||||
(int)$sogo_access = (isset($_data['sogo_access'])) ? intval($_data['sogo_access']) : intval($is_now['attributes']['sogo_access']);
|
(int)$sogo_access = (isset($_data['sogo_access'])) ? intval($_data['sogo_access']) : intval($is_now['attributes']['sogo_access']);
|
||||||
|
(int)$quota_m = (isset_has_content($_data['quota'])) ? intval($_data['quota']) : ($is_now['quota'] / 1048576);
|
||||||
$name = (!empty($_data['name'])) ? ltrim(rtrim($_data['name'], '>'), '<') : $is_now['name'];
|
$name = (!empty($_data['name'])) ? ltrim(rtrim($_data['name'], '>'), '<') : $is_now['name'];
|
||||||
$domain = $is_now['domain'];
|
$domain = $is_now['domain'];
|
||||||
$quota_m = (!empty($_data['quota'])) ? $_data['quota'] : ($is_now['quota'] / 1048576);
|
|
||||||
$quota_b = $quota_m * 1048576;
|
$quota_b = $quota_m * 1048576;
|
||||||
$password = (!empty($_data['password'])) ? $_data['password'] : null;
|
$password = (!empty($_data['password'])) ? $_data['password'] : null;
|
||||||
$password2 = (!empty($_data['password2'])) ? $_data['password2'] : null;
|
$password2 = (!empty($_data['password2'])) ? $_data['password2'] : null;
|
||||||
@@ -2008,6 +2008,15 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// if already 0 == ok
|
||||||
|
if ((!isset($_SESSION['acl']['unlimited_quota']) || $_SESSION['acl']['unlimited_quota'] != "1") && ($quota_m == 0 && $is_now['quota'] != 0)) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => 'unlimited_quota_acl'
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$stmt = $pdo->prepare("SELECT `quota`, `maxquota`
|
$stmt = $pdo->prepare("SELECT `quota`, `maxquota`
|
||||||
FROM `domain`
|
FROM `domain`
|
||||||
WHERE `domain` = :domain");
|
WHERE `domain` = :domain");
|
||||||
@@ -2021,14 +2030,6 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!is_numeric($quota_m) || $quota_m == "0") {
|
|
||||||
$_SESSION['return'][] = array(
|
|
||||||
'type' => 'danger',
|
|
||||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
|
||||||
'msg' => array('quota_not_0_not_numeric', htmlspecialchars($quota_m))
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ($quota_m > $DomainData['maxquota']) {
|
if ($quota_m > $DomainData['maxquota']) {
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
'type' => 'danger',
|
'type' => 'danger',
|
||||||
@@ -3016,15 +3017,18 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
$mailboxdata['quota'] = $row['quota'];
|
$mailboxdata['quota'] = $row['quota'];
|
||||||
$mailboxdata['attributes'] = json_decode($row['attributes'], true);
|
$mailboxdata['attributes'] = json_decode($row['attributes'], true);
|
||||||
$mailboxdata['quota_used'] = intval($row['bytes']);
|
$mailboxdata['quota_used'] = intval($row['bytes']);
|
||||||
$mailboxdata['percent_in_use'] = round((intval($row['bytes']) / intval($row['quota'])) * 100);
|
$mailboxdata['percent_in_use'] = ($row['quota'] == 0) ? '- ' : round((intval($row['bytes']) / intval($row['quota'])) * 100);
|
||||||
$mailboxdata['messages'] = $row['messages'];
|
$mailboxdata['messages'] = $row['messages'];
|
||||||
$mailboxdata['spam_aliases'] = $SpamaliasUsage['sa_count'];
|
$mailboxdata['spam_aliases'] = $SpamaliasUsage['sa_count'];
|
||||||
if ($mailboxdata['percent_in_use'] >= 90) {
|
if ($mailboxdata['percent_in_use'] === '- ') {
|
||||||
$mailboxdata['percent_class'] = "danger";
|
$mailboxdata['percent_class'] = "info";
|
||||||
}
|
}
|
||||||
elseif ($mailboxdata['percent_in_use'] >= 75) {
|
elseif ($mailboxdata['percent_in_use'] >= 75) {
|
||||||
$mailboxdata['percent_class'] = "warning";
|
$mailboxdata['percent_class'] = "warning";
|
||||||
}
|
}
|
||||||
|
elseif ($mailboxdata['percent_in_use'] >= 90) {
|
||||||
|
$mailboxdata['percent_class'] = "danger";
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
$mailboxdata['percent_class'] = "success";
|
$mailboxdata['percent_class'] = "success";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ function init_db_schema() {
|
|||||||
try {
|
try {
|
||||||
global $pdo;
|
global $pdo;
|
||||||
|
|
||||||
$db_version = "27012019_1217";
|
$db_version = "30032019_1905";
|
||||||
|
|
||||||
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
@@ -464,6 +464,7 @@ function init_db_schema() {
|
|||||||
"filters" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
"filters" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||||
"ratelimit" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
"ratelimit" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||||
"spam_policy" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
"spam_policy" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||||
|
"unlimited_quota" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
"alias_domains" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
"alias_domains" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
),
|
),
|
||||||
"keys" => array(
|
"keys" => array(
|
||||||
|
|||||||
@@ -75,6 +75,24 @@ if (!empty($_SERVER['HTTP_X_API_KEY'])) {
|
|||||||
// Update session cookie
|
// Update session cookie
|
||||||
// setcookie(session_name() ,session_id(), time() + $SESSION_LIFETIME);
|
// setcookie(session_name() ,session_id(), time() + $SESSION_LIFETIME);
|
||||||
|
|
||||||
|
// Handle logouts
|
||||||
|
if (isset($_POST["logout"])) {
|
||||||
|
if (isset($_SESSION["dual-login"])) {
|
||||||
|
$_SESSION["mailcow_cc_username"] = $_SESSION["dual-login"]["username"];
|
||||||
|
$_SESSION["mailcow_cc_role"] = $_SESSION["dual-login"]["role"];
|
||||||
|
unset($_SESSION["dual-login"]);
|
||||||
|
header("Location: /mailbox");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
session_regenerate_id(true);
|
||||||
|
session_unset();
|
||||||
|
session_destroy();
|
||||||
|
session_write_close();
|
||||||
|
header("Location: /");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check session
|
// Check session
|
||||||
function session_check() {
|
function session_check() {
|
||||||
if (isset($_SESSION['mailcow_cc_api']) && $_SESSION['mailcow_cc_api'] === true) {
|
if (isset($_SESSION['mailcow_cc_api']) && $_SESSION['mailcow_cc_api'] === true) {
|
||||||
@@ -106,21 +124,3 @@ if (isset($_SESSION['mailcow_cc_role']) && session_check() === false) {
|
|||||||
$_POST = array();
|
$_POST = array();
|
||||||
$_FILES = array();
|
$_FILES = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle logouts
|
|
||||||
if (isset($_POST["logout"])) {
|
|
||||||
if (isset($_SESSION["dual-login"])) {
|
|
||||||
$_SESSION["mailcow_cc_username"] = $_SESSION["dual-login"]["username"];
|
|
||||||
$_SESSION["mailcow_cc_role"] = $_SESSION["dual-login"]["role"];
|
|
||||||
unset($_SESSION["dual-login"]);
|
|
||||||
header("Location: /mailbox");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
session_regenerate_id(true);
|
|
||||||
session_unset();
|
|
||||||
session_destroy();
|
|
||||||
session_write_close();
|
|
||||||
header("Location: /");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+3
-3
@@ -1,5 +1,5 @@
|
|||||||
/*! =======================================================
|
/*! =======================================================
|
||||||
VERSION 10.6.0
|
VERSION 10.6.1
|
||||||
========================================================= */
|
========================================================= */
|
||||||
"use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},windowIsDefined="object"===("undefined"==typeof window?"undefined":_typeof(window));!function(a){if("function"==typeof define&&define.amd)define(["jquery"],a);else if("object"===("undefined"==typeof module?"undefined":_typeof(module))&&module.exports){var b;try{b=require("jquery")}catch(c){b=null}module.exports=a(b)}else window&&(window.Slider=a(window.jQuery))}(function(a){var b="slider",c="bootstrapSlider";windowIsDefined&&!window.console&&(window.console={}),windowIsDefined&&!window.console.log&&(window.console.log=function(){}),windowIsDefined&&!window.console.warn&&(window.console.warn=function(){});var d;return function(a){function b(){}function c(a){function c(b){b.prototype.option||(b.prototype.option=function(b){a.isPlainObject(b)&&(this.options=a.extend(!0,this.options,b))})}function e(b,c){a.fn[b]=function(e){if("string"==typeof e){for(var g=d.call(arguments,1),h=0,i=this.length;i>h;h++){var j=this[h],k=a.data(j,b);if(k)if(a.isFunction(k[e])&&"_"!==e.charAt(0)){var l=k[e].apply(k,g);if(void 0!==l&&l!==k)return l}else f("no such method '"+e+"' for "+b+" instance");else f("cannot call methods on "+b+" prior to initialization; attempted to call '"+e+"'")}return this}var m=this.map(function(){var d=a.data(this,b);return d?(d.option(e),d._init()):(d=new c(this,e),a.data(this,b,d)),a(this)});return!m||m.length>1?m:m[0]}}if(a){var f="undefined"==typeof console?b:function(a){console.error(a)};return a.bridget=function(a,b){c(b),e(a,b)},a.bridget}}var d=Array.prototype.slice;c(a)}(a),function(a){function e(b,c){function d(a,b){var c="data-slider-"+b.replace(/_/g,"-"),d=a.getAttribute(c);try{return JSON.parse(d)}catch(e){return d}}this._state={value:null,enabled:null,offset:null,size:null,percentage:null,inDrag:!1,over:!1,tickIndex:null},this.ticksCallbackMap={},this.handleCallbackMap={},"string"==typeof b?this.element=document.querySelector(b):b instanceof HTMLElement&&(this.element=b),c=c?c:{};for(var e=Object.keys(this.defaultOptions),f=c.hasOwnProperty("min"),g=c.hasOwnProperty("max"),i=0;i<e.length;i++){var j=e[i],k=c[j];k="undefined"!=typeof k?k:d(this.element,j),k=null!==k?k:this.defaultOptions[j],this.options||(this.options={}),this.options[j]=k}if(this.ticksAreValid=Array.isArray(this.options.ticks)&&this.options.ticks.length>0,this.ticksAreValid||(this.options.lock_to_ticks=!1),"auto"===this.options.rtl){var l=window.getComputedStyle(this.element);null!=l?this.options.rtl="rtl"===l.direction:this.options.rtl="rtl"===this.element.style.direction}"vertical"!==this.options.orientation||"top"!==this.options.tooltip_position&&"bottom"!==this.options.tooltip_position?"horizontal"!==this.options.orientation||"left"!==this.options.tooltip_position&&"right"!==this.options.tooltip_position||(this.options.tooltip_position="top"):this.options.rtl?this.options.tooltip_position="left":this.options.tooltip_position="right";var m,n,o,p,q,r=this.element.style.width,s=!1,t=this.element.parentNode;if(this.sliderElem)s=!0;else{this.sliderElem=document.createElement("div"),this.sliderElem.className="slider";var u=document.createElement("div");u.className="slider-track",n=document.createElement("div"),n.className="slider-track-low",m=document.createElement("div"),m.className="slider-selection",o=document.createElement("div"),o.className="slider-track-high",p=document.createElement("div"),p.className="slider-handle min-slider-handle",p.setAttribute("role","slider"),p.setAttribute("aria-valuemin",this.options.min),p.setAttribute("aria-valuemax",this.options.max),q=document.createElement("div"),q.className="slider-handle max-slider-handle",q.setAttribute("role","slider"),q.setAttribute("aria-valuemin",this.options.min),q.setAttribute("aria-valuemax",this.options.max),u.appendChild(n),u.appendChild(m),u.appendChild(o),this.rangeHighlightElements=[];var v=this.options.rangeHighlights;if(Array.isArray(v)&&v.length>0)for(var w=0;w<v.length;w++){var x=document.createElement("div"),y=v[w]["class"]||"";x.className="slider-rangeHighlight slider-selection "+y,this.rangeHighlightElements.push(x),u.appendChild(x)}var z=Array.isArray(this.options.labelledby);if(z&&this.options.labelledby[0]&&p.setAttribute("aria-labelledby",this.options.labelledby[0]),z&&this.options.labelledby[1]&&q.setAttribute("aria-labelledby",this.options.labelledby[1]),!z&&this.options.labelledby&&(p.setAttribute("aria-labelledby",this.options.labelledby),q.setAttribute("aria-labelledby",this.options.labelledby)),this.ticks=[],Array.isArray(this.options.ticks)&&this.options.ticks.length>0){for(this.ticksContainer=document.createElement("div"),this.ticksContainer.className="slider-tick-container",i=0;i<this.options.ticks.length;i++){var A=document.createElement("div");if(A.className="slider-tick",this.options.ticks_tooltip){var B=this._aLine truncated
|
"use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},windowIsDefined="object"===("undefined"==typeof window?"undefined":_typeof(window));!function(a){if("function"==typeof define&&define.amd)define(["jquery"],a);else if("object"===("undefined"==typeof module?"undefined":_typeof(module))&&module.exports){var b;try{b=require("jquery")}catch(c){b=null}module.exports=a(b)}else window&&(window.Slider=a(window.jQuery))}(function(a){var b="slider",c="bootstrapSlider";windowIsDefined&&!window.console&&(window.console={}),windowIsDefined&&!window.console.log&&(window.console.log=function(){}),windowIsDefined&&!window.console.warn&&(window.console.warn=function(){});var d;return function(a){function b(){}function c(a){function c(b){b.prototype.option||(b.prototype.option=function(b){a.isPlainObject(b)&&(this.options=a.extend(!0,this.options,b))})}function e(b,c){a.fn[b]=function(e){if("string"==typeof e){for(var g=d.call(arguments,1),h=0,i=this.length;i>h;h++){var j=this[h],k=a.data(j,b);if(k)if(a.isFunction(k[e])&&"_"!==e.charAt(0)){var l=k[e].apply(k,g);if(void 0!==l&&l!==k)return l}else f("no such method '"+e+"' for "+b+" instance");else f("cannot call methods on "+b+" prior to initialization; attempted to call '"+e+"'")}return this}var m=this.map(function(){var d=a.data(this,b);return d?(d.option(e),d._init()):(d=new c(this,e),a.data(this,b,d)),a(this)});return!m||m.length>1?m:m[0]}}if(a){var f="undefined"==typeof console?b:function(a){console.error(a)};return a.bridget=function(a,b){c(b),e(a,b)},a.bridget}}var d=Array.prototype.slice;c(a)}(a),function(a){function e(b,c){function d(a,b){var c="data-slider-"+b.replace(/_/g,"-"),d=a.getAttribute(c);try{return JSON.parse(d)}catch(e){return d}}this._state={value:null,enabled:null,offset:null,size:null,percentage:null,inDrag:!1,over:!1,tickIndex:null},this.ticksCallbackMap={},this.handleCallbackMap={},"string"==typeof b?this.element=document.querySelector(b):b instanceof HTMLElement&&(this.element=b),c=c?c:{};for(var e=Object.keys(this.defaultOptions),f=c.hasOwnProperty("min"),g=c.hasOwnProperty("max"),i=0;i<e.length;i++){var j=e[i],k=c[j];k="undefined"!=typeof k?k:d(this.element,j),k=null!==k?k:this.defaultOptions[j],this.options||(this.options={}),this.options[j]=k}if(this.ticksAreValid=Array.isArray(this.options.ticks)&&this.options.ticks.length>0,this.ticksAreValid||(this.options.lock_to_ticks=!1),"auto"===this.options.rtl){var l=window.getComputedStyle(this.element);null!=l?this.options.rtl="rtl"===l.direction:this.options.rtl="rtl"===this.element.style.direction}"vertical"!==this.options.orientation||"top"!==this.options.tooltip_position&&"bottom"!==this.options.tooltip_position?"horizontal"!==this.options.orientation||"left"!==this.options.tooltip_position&&"right"!==this.options.tooltip_position||(this.options.tooltip_position="top"):this.options.rtl?this.options.tooltip_position="left":this.options.tooltip_position="right";var m,n,o,p,q,r=this.element.style.width,s=!1,t=this.element.parentNode;if(this.sliderElem)s=!0;else{this.sliderElem=document.createElement("div"),this.sliderElem.className="slider";var u=document.createElement("div");u.className="slider-track",n=document.createElement("div"),n.className="slider-track-low",m=document.createElement("div"),m.className="slider-selection",o=document.createElement("div"),o.className="slider-track-high",p=document.createElement("div"),p.className="slider-handle min-slider-handle",p.setAttribute("role","slider"),p.setAttribute("aria-valuemin",this.options.min),p.setAttribute("aria-valuemax",this.options.max),q=document.createElement("div"),q.className="slider-handle max-slider-handle",q.setAttribute("role","slider"),q.setAttribute("aria-valuemin",this.options.min),q.setAttribute("aria-valuemax",this.options.max),u.appendChild(n),u.appendChild(m),u.appendChild(o),this.rangeHighlightElements=[];var v=this.options.rangeHighlights;if(Array.isArray(v)&&v.length>0)for(var w=0;w<v.length;w++){var x=document.createElement("div"),y=v[w]["class"]||"";x.className="slider-rangeHighlight slider-selection "+y,this.rangeHighlightElements.push(x),u.appendChild(x)}var z=Array.isArray(this.options.labelledby);if(z&&this.options.labelledby[0]&&p.setAttribute("aria-labelledby",this.options.labelledby[0]),z&&this.options.labelledby[1]&&q.setAttribute("aria-labelledby",this.options.labelledby[1]),!z&&this.options.labelledby&&(p.setAttribute("aria-labelledby",this.options.labelledby),q.setAttribute("aria-labelledby",this.options.labelledby)),this.ticks=[],Array.isArray(this.options.ticks)&&this.options.ticks.length>0){for(this.ticksContainer=document.createElement("div"),this.ticksContainer.className="slider-tick-container",i=0;i<this.options.ticks.length;i++){var A=document.createElement("div");if(A.className="slider-tick",this.options.ticks_tooltip){var B=this._aLine truncated
|
||||||
this._state.keyCtrl=1,this.handle2.focus()):1===this._state.keyCtrl&&this._toPercentage(this._state.value[0])>a&&(this._state.percentage[1]=this._state.percentage[0],this._state.keyCtrl=0,this.handle1.focus())}},_mouseup:function(a){if(!this._state.enabled)return!1;var b=this._getPercentage(a);this._adjustPercentageForRangeSliders(b),this._state.percentage[this._state.dragged]=b,this.touchCapable&&(document.removeEventListener("touchmove",this.mousemove,!1),document.removeEventListener("touchend",this.mouseup,!1)),document.removeEventListener("mousemove",this.mousemove,!1),document.removeEventListener("mouseup",this.mouseup,!1),this._state.inDrag=!1,this._state.over===!1&&this._hideTooltip();var c=this._calculateValue(!0);return this.setValue(c,!1,!0),this._trigger("slideStop",c),this._state.dragged=null,!1},_setValues:function(a,b){var c=0===a?0:100;this._state.percentage[a]!==c&&(b.data[a]=this._toValue(this._state.percentage[a]),b.data[a]=this._applyPrecision(b.data[a]))},_calculateValue:function(a){var b={};return this.options.range?(b.data=[this.options.min,this.options.max],this._setValues(0,b),this._setValues(1,b),a&&(b.data[0]=this._snapToClosestTick(b.data[0]),b.data[1]=this._snapToClosestTick(b.data[1]))):(b.data=this._toValue(this._state.percentage[0]),b.data=parseFloat(b.data),b.data=this._applyPrecision(b.data),a&&(b.data=this._snapToClosestTick(b.data))),b.data},_snapToClosestTick:function(a){for(var b=[a,1/0],c=0;c<this.options.ticks.length;c++){var d=Math.abs(this.options.ticks[c]-a);d<=b[1]&&(b=[this.options.ticks[c],d])}return b[1]<=this.options.ticks_snap_bounds?b[0]:a},_applyPrecision:function(a){var b=this.options.precision||this._getNumDigitsAfterDecimalPlace(this.options.step);return this._applyToFixedAndParseFloat(a,b)},_getNumDigitsAfterDecimalPlace:function(a){var b=(""+a).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);return b?Math.max(0,(b[1]?b[1].length:0)-(b[2]?+b[2]:0)):0},_applyToFixedAndParseFloat:function(a,b){var c=a.toFixed(b);return parseFloat(c)},_getPercentage:function(a){!this.touchCapable||"touchstart"!==a.type&&"touchmove"!==a.type||(a=a.touches[0]);var b=a[this.mousePos],c=this._state.offset[this.stylePos],d=b-c;"right"===this.stylePos&&(d=-d);var e=d/this._state.size*100;return e=Math.round(e/this._state.percentage[2])*this._state.percentage[2],this.options.reversed&&(e=100-e),Math.max(0,Math.min(100,e))},_validateInputValue:function(a){if(isNaN(+a)){if(Array.isArray(a))return this._validateArray(a),a;throw new Error(g.formatInvalidInputErrorMsg(a))}return+a},_validateArray:function(a){for(var b=0;b<a.length;b++){var c=a[b];if("number"!=typeof c)throw new Error(g.formatInvalidInputErrorMsg(c))}},_setDataVal:function(a){this.element.setAttribute("data-value",a),this.element.setAttribute("value",a),this.element.value=a},_trigger:function(b,c){c=c||0===c?c:void 0;var d=this.eventToCallbackMap[b];if(d&&d.length)for(var e=0;e<d.length;e++){var f=d[e];f(c)}a&&this._triggerJQueryEvent(b,c)},_triggerJQueryEvent:function(a,b){var c={type:a,value:b};this.$element.trigger(c),this.$sliderElem.trigger(c)},_unbindJQueryEventHandlers:function(){this.$element.off(),this.$sliderElem.off()},_setText:function(a,b){"undefined"!=typeof a.textContent?a.textContent=b:"undefined"!=typeof a.innerText&&(a.innerText=b)},_removeClass:function(a,b){for(var c=b.split(" "),d=a.className,e=0;e<c.length;e++){var f=c[e],g=new RegExp("(?:\\s|^)"+f+"(?:\\s|$)");d=d.replace(g," ")}a.className=d.trim()},_addClass:function(a,b){for(var c=b.split(" "),d=a.className,e=0;e<c.length;e++){var f=c[e],g=new RegExp("(?:\\s|^)"+f+"(?:\\s|$)"),h=g.test(d);h||(d+=" "+f)}a.className=d.trim()},_offsetLeft:function(a){return a.getBoundingClientRect().left},_offsetRight:function(a){return a.getBoundingClientRect().right},_offsetTop:function(a){for(var b=a.offsetTop;(a=a.offsetParent)&&!isNaN(a.offsetTop);)b+=a.offsetTop,"BODY"!==a.tagName&&(b-=a.scrollTop);return b},_offset:function(a){return{left:this._offsetLeft(a),right:this._offsetRight(a),top:this._offsetTop(a)}},_css:function(b,c,d){if(a)a.style(b,c,d);else{var e=c.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(a,b){return b.toUpperCase()});b.style[e]=d}},_toValue:function(a){return this.options.scale.toValue.apply(this,[a])},_toPercentage:function(a){return this.options.scale.toPercentage.apply(this,[a])},_setTooltipPosition:function(){var a=[this.tooltip,this.tooltip_min,this.tooltip_max];if("vertical"===this.options.orientation){var b;b=this.options.tooltip_position?this.options.tooltip_position:this.options.rtl?"left":"right";var c="left"===b?"right":"left";a.forEach(function(a){this._addClass(a,b),a.style[c]="100%"}.bind(this))}else"bottom"===this.options.tooltip_position?a.forEach(function(a){this._addClass(a,"bottom"),a.style.top="22px"}.bind(this)):a.forEach(function(a){this._addClass(a,"top"),a.style.top=-this.tooltip.outerHeight-14+"px"}.bind(this))},_getClosestTickIndex:function(a){for(var b=Math.abs(a-this.options.ticks[0]),c=0,d=0;d<this.optionLine truncated
|
var b=this._getPercentage(a);this._adjustPercentageForRangeSliders(b),this._state.percentage[this._state.dragged]=b;var c=this._calculateValue(!0);return this.setValue(c,!0,!0),!1},_touchmove:function(a){void 0!==a.changedTouches&&a.preventDefault&&a.preventDefault()},_adjustPercentageForRangeSliders:function(a){if(this.options.range){var b=this._getNumDigitsAfterDecimalPlace(a);b=b?b-1:0;var c=this._applyToFixedAndParseFloat(a,b);0===this._state.dragged&&this._applyToFixedAndParseFloat(this._state.percentage[1],b)<c?(this._state.percentage[0]=this._state.percentage[1],this._state.dragged=1):1===this._state.dragged&&this._applyToFixedAndParseFloat(this._state.percentage[0],b)>c?(this._state.percentage[1]=this._state.percentage[0],this._state.dragged=0):0===this._state.keyCtrl&&this._toPercentage(this._state.value[1])<a?(this._state.percentage[0]=this._state.percentage[1],this._state.keyCtrl=1,this.handle2.focus()):1===this._state.keyCtrl&&this._toPercentage(this._state.value[0])>a&&(this._state.percentage[1]=this._state.percentage[0],this._state.keyCtrl=0,this.handle1.focus())}},_mouseup:function(a){if(!this._state.enabled)return!1;var b=this._getPercentage(a);this._adjustPercentageForRangeSliders(b),this._state.percentage[this._state.dragged]=b,this.touchCapable&&(document.removeEventListener("touchmove",this.mousemove,!1),document.removeEventListener("touchend",this.mouseup,!1)),document.removeEventListener("mousemove",this.mousemove,!1),document.removeEventListener("mouseup",this.mouseup,!1),this._state.inDrag=!1,this._state.over===!1&&this._hideTooltip();var c=this._calculateValue(!0);return this.setValue(c,!1,!0),this._trigger("slideStop",c),this._state.dragged=null,!1},_setValues:function(a,b){var c=0===a?0:100;this._state.percentage[a]!==c&&(b.data[a]=this._toValue(this._state.percentage[a]),b.data[a]=this._applyPrecision(b.data[a]))},_calculateValue:function(a){var b={};return this.options.range?(b.data=[this.options.min,this.options.max],this._setValues(0,b),this._setValues(1,b),a&&(b.data[0]=this._snapToClosestTick(b.data[0]),b.data[1]=this._snapToClosestTick(b.data[1]))):(b.data=this._toValue(this._state.percentage[0]),b.data=parseFloat(b.data),b.data=this._applyPrecision(b.data),a&&(b.data=this._snapToClosestTick(b.data))),b.data},_snapToClosestTick:function(a){for(var b=[a,1/0],c=0;c<this.options.ticks.length;c++){var d=Math.abs(this.options.ticks[c]-a);d<=b[1]&&(b=[this.options.ticks[c],d])}return b[1]<=this.options.ticks_snap_bounds?b[0]:a},_applyPrecision:function(a){var b=this.options.precision||this._getNumDigitsAfterDecimalPlace(this.options.step);return this._applyToFixedAndParseFloat(a,b)},_getNumDigitsAfterDecimalPlace:function(a){var b=(""+a).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);return b?Math.max(0,(b[1]?b[1].length:0)-(b[2]?+b[2]:0)):0},_applyToFixedAndParseFloat:function(a,b){var c=a.toFixed(b);return parseFloat(c)},_getPercentage:function(a){!this.touchCapable||"touchstart"!==a.type&&"touchmove"!==a.type&&"touchend"!==a.type||(a=a.changedTouches[0]);var b=a[this.mousePos],c=this._state.offset[this.stylePos],d=b-c;"right"===this.stylePos&&(d=-d);var e=d/this._state.size*100;return e=Math.round(e/this._state.percentage[2])*this._state.percentage[2],this.options.reversed&&(e=100-e),Math.max(0,Math.min(100,e))},_validateInputValue:function(a){if(isNaN(+a)){if(Array.isArray(a))return this._validateArray(a),a;throw new Error(g.formatInvalidInputErrorMsg(a))}return+a},_validateArray:function(a){for(var b=0;b<a.length;b++){var c=a[b];if("number"!=typeof c)throw new Error(g.formatInvalidInputErrorMsg(c))}},_setDataVal:function(a){this.element.setAttribute("data-value",a),this.element.setAttribute("value",a),this.element.value=a},_trigger:function(b,c){c=c||0===c?c:void 0;var d=this.eventToCallbackMap[b];if(d&&d.length)for(var e=0;e<d.length;e++){var f=d[e];f(c)}a&&this._triggerJQueryEvent(b,c)},_triggerJQueryEvent:function(a,b){var c={type:a,value:b};this.$element.trigger(c),this.$sliderElem.trigger(c)},_unbindJQueryEventHandlers:function(){this.$element.off(),this.$sliderElem.off()},_setText:function(a,b){"undefined"!=typeof a.textContent?a.textContent=b:"undefined"!=typeof a.innerText&&(a.innerText=b)},_removeClass:function(a,b){for(var c=b.split(" "),d=a.className,e=0;e<c.length;e++){var f=c[e],g=new RegExp("(?:\\s|^)"+f+"(?:\\s|$)");d=d.replace(g," ")}a.className=d.trim()},_addClass:function(a,b){for(var c=b.split(" "),d=a.className,e=0;e<c.length;e++){var f=c[e],g=new RegExp("(?:\\s|^)"+f+"(?:\\s|$)"),h=g.test(d);h||(d+=" "+f)}a.className=d.trim()},_offsetLeft:function(a){return a.getBoundingClientRect().left},_offsetRight:function(a){return a.getBoundingClientRect().right},_offsetTop:function(a){for(var b=a.offsetTop;(a=a.offsetParent)&&!isNaN(a.offsetTop);)b+=a.offsetTop,"BODY"!==a.tagName&&(b-=a.scrollTop);return b},_offset:function(a){return{left:this._offsetLeft(a),right:this._offsetRight(a),top:this._offsetTop(a)}},_css:function(b,c,d){if(a)a.style(b,c,d);else{var e=c.replaLine truncated
|
||||||
@@ -312,7 +312,8 @@ jQuery(function($){
|
|||||||
{"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
|
{"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
|
||||||
{"name":"quota","style":{"whiteSpace":"nowrap"},"title":lang.domain_quota,"formatter": function(value){
|
{"name":"quota","style":{"whiteSpace":"nowrap"},"title":lang.domain_quota,"formatter": function(value){
|
||||||
res = value.split("/");
|
res = value.split("/");
|
||||||
return humanFileSize(res[0]) + " / " + humanFileSize(res[1]);
|
var of_q = (res[1] == 0 ? "∞" : humanFileSize(res[1]));
|
||||||
|
return humanFileSize(res[0]) + " / " + of_q;
|
||||||
},
|
},
|
||||||
"sortValue": function(value){
|
"sortValue": function(value){
|
||||||
res = value.split("/");
|
res = value.split("/");
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ $lang['footer']['cancel'] = 'Abbrechen';
|
|||||||
$lang['footer']['hibp_nok'] = 'Übereinstimmung gefunden! Dieses Passwort ist potentiell gefährlich!';
|
$lang['footer']['hibp_nok'] = 'Übereinstimmung gefunden! Dieses Passwort ist potentiell gefährlich!';
|
||||||
$lang['footer']['hibp_ok'] = 'Keine Übereinstimmung gefunden.';
|
$lang['footer']['hibp_ok'] = 'Keine Übereinstimmung gefunden.';
|
||||||
|
|
||||||
|
$lang['danger']['unlimited_quota_acl'] = "Unendliche Quota untersagt durch ACL";
|
||||||
$lang['danger']['mysql_error'] = "MySQL Fehler: %s";
|
$lang['danger']['mysql_error'] = "MySQL Fehler: %s";
|
||||||
$lang['danger']['redis_error'] = "Redis Fehler: %s";
|
$lang['danger']['redis_error'] = "Redis Fehler: %s";
|
||||||
$lang['danger']['unknown_tfa_method'] = "Unbekannte TFA Methode";
|
$lang['danger']['unknown_tfa_method'] = "Unbekannte TFA Methode";
|
||||||
@@ -405,6 +406,7 @@ $lang['acl']['bcc_maps'] = 'BCC Maps';
|
|||||||
$lang['acl']['filters'] = 'Filter';
|
$lang['acl']['filters'] = 'Filter';
|
||||||
$lang['acl']['ratelimit'] = 'Rate limit';
|
$lang['acl']['ratelimit'] = 'Rate limit';
|
||||||
$lang['acl']['recipient_maps'] = 'Empfängerumschreibungen';
|
$lang['acl']['recipient_maps'] = 'Empfängerumschreibungen';
|
||||||
|
$lang['acl']['unlimited_quota'] = 'Unendliche Quota für Mailboxen';
|
||||||
$lang['acl']['prohibited'] = 'Untersagt durch Richtlinie';
|
$lang['acl']['prohibited'] = 'Untersagt durch Richtlinie';
|
||||||
|
|
||||||
$lang['mailbox']['quarantine_notification'] = 'Quarantäne-Benachrichtigung';
|
$lang['mailbox']['quarantine_notification'] = 'Quarantäne-Benachrichtigung';
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ $lang['footer']['cancel'] = 'Cancel';
|
|||||||
$lang['footer']['hibp_nok'] = 'Matched! This is a potentially dangerous password!';
|
$lang['footer']['hibp_nok'] = 'Matched! This is a potentially dangerous password!';
|
||||||
$lang['footer']['hibp_ok'] = 'No match found.';
|
$lang['footer']['hibp_ok'] = 'No match found.';
|
||||||
|
|
||||||
|
$lang['danger']['unlimited_quota_acl'] = "Unlimited quota prohibited by ACL";
|
||||||
$lang['danger']['mysql_error'] = "MySQL error: %s";
|
$lang['danger']['mysql_error'] = "MySQL error: %s";
|
||||||
$lang['danger']['redis_error'] = "Redis error: %s";
|
$lang['danger']['redis_error'] = "Redis error: %s";
|
||||||
$lang['danger']['unknown_tfa_method'] = "Unknown TFA method";
|
$lang['danger']['unknown_tfa_method'] = "Unknown TFA method";
|
||||||
@@ -418,6 +419,7 @@ $lang['acl']['bcc_maps'] = 'BCC maps';
|
|||||||
$lang['acl']['filters'] = 'Filters';
|
$lang['acl']['filters'] = 'Filters';
|
||||||
$lang['acl']['ratelimit'] = 'Rate limit';
|
$lang['acl']['ratelimit'] = 'Rate limit';
|
||||||
$lang['acl']['recipient_maps'] = 'Recipient maps';
|
$lang['acl']['recipient_maps'] = 'Recipient maps';
|
||||||
|
$lang['acl']['unlimited_quota'] = 'Unlimited quota for mailboxes';
|
||||||
$lang['acl']['prohibited'] = 'Prohibited by ACL';
|
$lang['acl']['prohibited'] = 'Prohibited by ACL';
|
||||||
|
|
||||||
$lang['mailbox']['quarantine_notification'] = 'Quarantine notifications';
|
$lang['mailbox']['quarantine_notification'] = 'Quarantine notifications';
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
|
|||||||
<br /><span id="quotaBadge" class="badge">max. - MiB</span>
|
<br /><span id="quotaBadge" class="badge">max. - MiB</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" name="quota" min="1" max="" id="addInputQuota" disabled value="<?=$lang['add']['select_domain'];?>" required>
|
<input type="text" class="form-control" name="quota" min="0" max="" id="addInputQuota" disabled value="<?=$lang['add']['select_domain'];?>" required>
|
||||||
<small class="help-block">min. 1</small>
|
<small class="help-block">0 = ∞</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
+2
-2
@@ -42,7 +42,7 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'doma
|
|||||||
foreach ($tfa_data['additional'] as $key_info): ?>
|
foreach ($tfa_data['additional'] as $key_info): ?>
|
||||||
<form style="display:inline;" method="post">
|
<form style="display:inline;" method="post">
|
||||||
<input type="hidden" name="unset_tfa_key" value="<?=$key_info['id'];?>" />
|
<input type="hidden" name="unset_tfa_key" value="<?=$key_info['id'];?>" />
|
||||||
<div class="label label-default">🔑 <?=$key_info['key_id'];?> <a href="#" style="font-weight:bold;color:white" onClick="$(this).closest('form').submit()">[<?=strtolower($lang['admin']['remove']);?>]</a></div>
|
<div class="label label-default">🔑 <?=$key_info['key_id'];?> <a href="#" style="font-weight:bold;color:white" onClick="$(this).closest('form').submit()">[<?=strtolower($lang['admin']['remove']);?>]</a></div>
|
||||||
</form>
|
</form>
|
||||||
<?php endforeach;
|
<?php endforeach;
|
||||||
endif;?>
|
endif;?>
|
||||||
@@ -199,7 +199,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||||||
<?=$mailboxdata['percent_in_use'];?>%
|
<?=$mailboxdata['percent_in_use'];?>%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p><?=formatBytes($mailboxdata['quota_used'], 2);?> / <?=formatBytes($mailboxdata['quota'], 2);?>, <?=$mailboxdata['messages'];?> <?=$lang['user']['messages'];?></p>
|
<p><?=formatBytes($mailboxdata['quota_used'], 2);?> / <?=($mailboxdata['quota'] == 0) ? '∞' : formatBytes($mailboxdata['quota'], 2);?><br><?=$mailboxdata['messages'];?> <?=$lang['user']['messages'];?></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
|||||||
+8
-4
@@ -158,6 +158,7 @@ services:
|
|||||||
- ./data/web/inc/init_db.inc.php:/init_db.inc.php
|
- ./data/web/inc/init_db.inc.php:/init_db.inc.php
|
||||||
- ./data/conf/sogo/custom-sogo.js:/usr/lib/GNUstep/SOGo/WebServerResources/js/custom-sogo.js
|
- ./data/conf/sogo/custom-sogo.js:/usr/lib/GNUstep/SOGo/WebServerResources/js/custom-sogo.js
|
||||||
- mysql-socket-vol-1:/var/run/mysqld/
|
- mysql-socket-vol-1:/var/run/mysqld/
|
||||||
|
- sogo-web-vol-1:/sogo_web
|
||||||
restart: always
|
restart: always
|
||||||
dns:
|
dns:
|
||||||
- ${IPV4_NETWORK:-172.22.1}.254
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
@@ -291,8 +292,7 @@ services:
|
|||||||
- ./data/assets/ssl/:/etc/ssl/mail/:ro
|
- ./data/assets/ssl/:/etc/ssl/mail/:ro
|
||||||
- ./data/conf/nginx/:/etc/nginx/conf.d/:rw
|
- ./data/conf/nginx/:/etc/nginx/conf.d/:rw
|
||||||
- ./data/conf/rspamd/meta_exporter:/meta_exporter:ro
|
- ./data/conf/rspamd/meta_exporter:/meta_exporter:ro
|
||||||
volumes_from:
|
- sogo-web-vol-1:/usr/lib/GNUstep/SOGo/
|
||||||
- sogo-mailcow
|
|
||||||
ports:
|
ports:
|
||||||
- "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
|
- "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
|
||||||
- "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
|
- "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
|
||||||
@@ -307,7 +307,7 @@ services:
|
|||||||
acme-mailcow:
|
acme-mailcow:
|
||||||
depends_on:
|
depends_on:
|
||||||
- nginx-mailcow
|
- nginx-mailcow
|
||||||
image: mailcow/acme:1.49
|
image: mailcow/acme:1.51
|
||||||
build: ./data/Dockerfiles/acme
|
build: ./data/Dockerfiles/acme
|
||||||
dns:
|
dns:
|
||||||
- ${IPV4_NETWORK:-172.22.1}.254
|
- ${IPV4_NETWORK:-172.22.1}.254
|
||||||
@@ -320,6 +320,7 @@ services:
|
|||||||
- DBPASS=${DBPASS}
|
- DBPASS=${DBPASS}
|
||||||
- SKIP_LETS_ENCRYPT=${SKIP_LETS_ENCRYPT:-n}
|
- SKIP_LETS_ENCRYPT=${SKIP_LETS_ENCRYPT:-n}
|
||||||
- SKIP_IP_CHECK=${SKIP_IP_CHECK:-n}
|
- SKIP_IP_CHECK=${SKIP_IP_CHECK:-n}
|
||||||
|
- SKIP_HTTP_VERIFICATION=${SKIP_HTTP_VERIFICATION:-n}
|
||||||
- LE_STAGING=${LE_STAGING:-n}
|
- LE_STAGING=${LE_STAGING:-n}
|
||||||
- TZ=${TZ}
|
- TZ=${TZ}
|
||||||
volumes:
|
volumes:
|
||||||
@@ -358,7 +359,7 @@ services:
|
|||||||
- /lib/modules:/lib/modules:ro
|
- /lib/modules:/lib/modules:ro
|
||||||
|
|
||||||
watchdog-mailcow:
|
watchdog-mailcow:
|
||||||
image: mailcow/watchdog:1.37
|
image: mailcow/watchdog:1.39
|
||||||
# Debug
|
# Debug
|
||||||
#command: /watchdog.sh
|
#command: /watchdog.sh
|
||||||
build: ./data/Dockerfiles/watchdog
|
build: ./data/Dockerfiles/watchdog
|
||||||
@@ -451,6 +452,8 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
mailcow-network:
|
mailcow-network:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
driver_opts:
|
||||||
|
com.docker.network.bridge.name: br-mailcow
|
||||||
enable_ipv6: true
|
enable_ipv6: true
|
||||||
ipam:
|
ipam:
|
||||||
driver: default
|
driver: default
|
||||||
@@ -470,3 +473,4 @@ volumes:
|
|||||||
solr-vol-1:
|
solr-vol-1:
|
||||||
postfix-vol-1:
|
postfix-vol-1:
|
||||||
crypt-vol-1:
|
crypt-vol-1:
|
||||||
|
sogo-web-vol-1:
|
||||||
@@ -186,6 +186,10 @@ SKIP_LETS_ENCRYPT=n
|
|||||||
|
|
||||||
SKIP_IP_CHECK=n
|
SKIP_IP_CHECK=n
|
||||||
|
|
||||||
|
# Skip HTTP verification in ACME container - y/n
|
||||||
|
|
||||||
|
SKIP_HTTP_VERIFICATION=n
|
||||||
|
|
||||||
# Skip ClamAV (clamd-mailcow) anti-virus (Rspamd will auto-detect a missing ClamAV container) - y/n
|
# Skip ClamAV (clamd-mailcow) anti-virus (Rspamd will auto-detect a missing ClamAV container) - y/n
|
||||||
|
|
||||||
SKIP_CLAMD=${SKIP_CLAMD}
|
SKIP_CLAMD=${SKIP_CLAMD}
|
||||||
|
|||||||
Reference in new issue
Block a user