diff --git a/.gitignore b/.gitignore index 4bb7ae26..5782cad9 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,7 @@ data/web/templates/cache/* data/web/.well-known/acme-challenge data/web/css/build/0081-custom-mailcow.css data/web/inc/vars.local.inc.php +data/web/inc/app_info.inc.php data/web/nextcloud*/ data/web/rc*/ docker-compose.override.yml diff --git a/data/web/api/openapi.yaml b/data/web/api/openapi.yaml index 8b6558de..ef8b0bd1 100644 --- a/data/web/api/openapi.yaml +++ b/data/web/api/openapi.yaml @@ -4805,7 +4805,7 @@ paths: schema: example: attr: - rl_vlaue: "10" + rl_value: "10" rl_frame: "h" items: - info@domain.tld @@ -4815,7 +4815,7 @@ paths: rl_frame: description: contains the frame for the ratelimit h,s,m type: string - rl_vlaue: + rl_value: description: contains the rate for the ratelimit 10,20,50,1 type: number type: object @@ -4876,7 +4876,7 @@ paths: schema: example: attr: - rl_vlaue: "10" + rl_value: "10" rl_frame: "h" items: - domain.tld @@ -4886,7 +4886,7 @@ paths: rl_frame: description: contains the frame for the ratelimit h,s,m type: string - rl_vlaue: + rl_value: description: contains the rate for the ratelimit 10,20,50,1 type: number type: object diff --git a/data/web/css/build/008-mailcow.css b/data/web/css/build/008-mailcow.css index 802d0353..d7533424 100644 --- a/data/web/css/build/008-mailcow.css +++ b/data/web/css/build/008-mailcow.css @@ -202,6 +202,11 @@ legend { margin-top: 27px; margin-bottom: 20px; color: #959595; + display: flex; + flex-direction: column; +} +.footer .version { + margin-left: auto; } .slave-info { padding: 15px 0px 15px 15px; diff --git a/data/web/inc/footer.inc.php b/data/web/inc/footer.inc.php index fedc7cdc..72482707 100644 --- a/data/web/inc/footer.inc.php +++ b/data/web/inc/footer.inc.php @@ -23,7 +23,12 @@ if (is_array($alertbox_log_parser)) { unset($_SESSION['return']); } +// globals $globalVariables = [ + 'mailcow_info' => array( + 'version_tag' => $GLOBALS['MAILCOW_GIT_VERSION'], + 'git_project_url' => $GLOBALS['MAILCOW_GIT_URL'] + ), 'js_path' => '/cache/'.basename($JSPath), 'pending_tfa_method' => @$_SESSION['pending_tfa_method'], 'pending_mailcow_cc_username' => @$_SESSION['pending_mailcow_cc_username'], diff --git a/data/web/inc/prerequisites.inc.php b/data/web/inc/prerequisites.inc.php index 59211f5e..6cfdd1ca 100644 --- a/data/web/inc/prerequisites.inc.php +++ b/data/web/inc/prerequisites.inc.php @@ -10,11 +10,17 @@ $DEV_MODE = (getenv('DEV_MODE') == 'y'); }*/ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/vars.inc.php'; + $default_autodiscover_config = $autodiscover_config; if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/inc/vars.local.inc.php')) { include_once $_SERVER['DOCUMENT_ROOT'] . '/inc/vars.local.inc.php'; } + +// auto-generated by generate-config.sh and update.sh +if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/inc/app_info.inc.php')) { + require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/app_info.inc.php'; +} unset($https_port); $autodiscover_config = array_merge($default_autodiscover_config, $autodiscover_config); diff --git a/data/web/inc/twig.inc.php b/data/web/inc/twig.inc.php index 081ca315..a3bc02d9 100644 --- a/data/web/inc/twig.inc.php +++ b/data/web/inc/twig.inc.php @@ -24,4 +24,4 @@ $twig->addFunction(new TwigFunction('is_uri', function (string $uri, string $whe // filters $twig->addFilter(new TwigFilter('rot13', 'str_rot13')); $twig->addFilter(new TwigFilter('base64_encode', 'base64_encode')); -$twig->addFilter(new TwigFilter('formatBytes', 'formatBytes')); +$twig->addFilter(new TwigFilter('formatBytes', 'formatBytes')); \ No newline at end of file diff --git a/data/web/json_api.php b/data/web/json_api.php index 278c1460..efe02340 100644 --- a/data/web/json_api.php +++ b/data/web/json_api.php @@ -409,16 +409,14 @@ if (isset($_GET['query'])) { break; case "fido2-get-args": header('Content-Type: application/json'); - // fetch allowed credentialIds - $cids = fido2(array("action" => "get_all_cids")); - if (count($cids) == 0) { - print(json_encode(array( - 'type' => 'error', - 'msg' => 'Cannot find matching credentialIds' - ))); - } + // Login without username, no ids! + // $ids = fido2(array("action" => "get_all_cids")); + // if (count($ids) == 0) { + // return; + // } + $ids = NULL; - $getArgs = $WebAuthn->getGetArgs($cids, 30, true, true, true, true, $GLOBALS['FIDO2_UV_FLAG_LOGIN']); + $getArgs = $WebAuthn->getGetArgs($ids, 30, true, true, true, true, $GLOBALS['FIDO2_UV_FLAG_LOGIN']); print(json_encode($getArgs)); $_SESSION['challenge'] = $WebAuthn->getChallenge(); return; diff --git a/data/web/sogo-auth.php b/data/web/sogo-auth.php index bb2673a4..7ca5e4d9 100644 --- a/data/web/sogo-auth.php +++ b/data/web/sogo-auth.php @@ -75,20 +75,26 @@ elseif (isset($_SERVER['HTTP_X_ORIGINAL_URI']) && strcasecmp(substr($_SERVER['HT session_start(); // extract email address from "/SOGo/so/user@domain/xy" $url_parts = explode("/", $_SERVER['HTTP_X_ORIGINAL_URI']); - $email = $url_parts[3]; - // check if this email is in session allowed list - if ( - !empty($email) && - filter_var($email, FILTER_VALIDATE_EMAIL) && - is_array($_SESSION[$session_var_user_allowed]) && - in_array($email, $_SESSION[$session_var_user_allowed]) - ) { - $username = $email; - $password = $_SESSION[$session_var_pass]; - header("X-User: $username"); - header("X-Auth: Basic ".base64_encode("$username:$password")); - header("X-Auth-Type: Basic"); - exit; + $email_list = array( + $url_parts[3], // Requested mailbox + ($_SESSION['mailcow_cc_username'] ?? ''), // Current user + ($_SESSION["dual-login"]["username"] ?? ''), // Dual login user + ); + foreach($email_list as $email) { + // check if this email is in session allowed list + if ( + !empty($email) && + filter_var($email, FILTER_VALIDATE_EMAIL) && + is_array($_SESSION[$session_var_user_allowed]) && + in_array($email, $_SESSION[$session_var_user_allowed]) + ) { + $username = $email; + $password = $_SESSION[$session_var_pass]; + header("X-User: $username"); + header("X-Auth: Basic ".base64_encode("$username:$password")); + header("X-Auth-Type: Basic"); + exit; + } } } diff --git a/data/web/templates/admin.twig b/data/web/templates/admin.twig index ad96c585..8d61cba6 100644 --- a/data/web/templates/admin.twig +++ b/data/web/templates/admin.twig @@ -38,22 +38,24 @@
- {% include 'admin/tab-config-admins.twig' %} - {% include 'admin/tab-ldap.twig' %} - {% include 'admin/tab-config-oauth2.twig' %} - {% include 'admin/tab-config-rspamd.twig' %} - {% include 'admin/tab-routing.twig' %} - {% include 'admin/tab-config-dkim.twig' %} - {% include 'admin/tab-config-fwdhosts.twig' %} - {% include 'admin/tab-config-f2b.twig' %} - {% include 'admin/tab-config-quarantine.twig' %} - {% include 'admin/tab-config-quota.twig' %} - {% include 'admin/tab-config-rsettings.twig' %} - {% include 'admin/tab-config-customize.twig' %} - {% include 'admin/tab-config-password-policy.twig' %} - {% include 'admin/tab-sys-mails.twig' %} - {% include 'admin/tab-mailq.twig' %} - {% include 'admin/tab-globalfilter-regex.twig' %} +
+ {% include 'admin/tab-config-admins.twig' %} + {% include 'admin/tab-ldap.twig' %} + {% include 'admin/tab-config-oauth2.twig' %} + {% include 'admin/tab-config-rspamd.twig' %} + {% include 'admin/tab-routing.twig' %} + {% include 'admin/tab-config-dkim.twig' %} + {% include 'admin/tab-config-fwdhosts.twig' %} + {% include 'admin/tab-config-f2b.twig' %} + {% include 'admin/tab-config-quarantine.twig' %} + {% include 'admin/tab-config-quota.twig' %} + {% include 'admin/tab-config-rsettings.twig' %} + {% include 'admin/tab-config-customize.twig' %} + {% include 'admin/tab-config-password-policy.twig' %} + {% include 'admin/tab-sys-mails.twig' %} + {% include 'admin/tab-mailq.twig' %} + {% include 'admin/tab-globalfilter-regex.twig' %} +
diff --git a/data/web/templates/admin/tab-config-admins.twig b/data/web/templates/admin/tab-config-admins.twig index cfb69d4d..d2eb4072 100644 --- a/data/web/templates/admin/tab-config-admins.twig +++ b/data/web/templates/admin/tab-config-admins.twig @@ -1,5 +1,4 @@ -
-
+
{{ lang.admin.admin_details }}
@@ -61,7 +60,8 @@ {{ lang.admin.action }} {% include 'fido2.twig' %} - + +

@@ -221,8 +221,6 @@
- -
{{ lang.admin.domain_admins }}
@@ -248,3 +246,4 @@
+ diff --git a/data/web/templates/base.twig b/data/web/templates/base.twig index d6f6d0b8..08376e71 100644 --- a/data/web/templates/base.twig +++ b/data/web/templates/base.twig @@ -423,6 +423,14 @@ function recursiveBase64StrToArrayBuffer(obj) { {% if ui_texts.ui_footer %}
{{ ui_texts.ui_footer|rot13|raw }} {% endif %} + {% if mailcow_cc_username and mailcow_info.version_tag|default %} + + 🐮 + 🐋 = 💕 + + Version: {{ mailcow_info.version_tag }} + + + {% endif %} diff --git a/docker-compose.yml b/docker-compose.yml index 57d07e8f..d706d2dc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -200,7 +200,7 @@ services: ofelia.job-exec.sogo_sessions.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu sogo /usr/sbin/sogo-tool expire-sessions $${SOGO_EXPIRE_SESSION} || exit 0\"" ofelia.job-exec.sogo_ealarms.schedule: "@every 1m" ofelia.job-exec.sogo_ealarms.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu sogo /usr/sbin/sogo-ealarms-notify -p /etc/sogo/sieve.creds || exit 0\"" - ofelia.job-exec.sogo_eautoreply.schedule: "@every 24h" + ofelia.job-exec.sogo_eautoreply.schedule: "@every 5m" ofelia.job-exec.sogo_eautoreply.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu sogo /usr/sbin/sogo-tool update-autoreply -p /etc/sogo/sieve.creds || exit 0\"" ofelia.job-exec.sogo_backup.schedule: "@every 24h" ofelia.job-exec.sogo_backup.command: "/bin/bash -c \"[[ $${MASTER} == y ]] && /usr/local/bin/gosu sogo /usr/sbin/sogo-tool backup /sogo_backup ALL || exit 0\"" diff --git a/generate_config.sh b/generate_config.sh index dceca957..e6f322ac 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -361,3 +361,19 @@ echo "Generating snake-oil certificate..." openssl req -x509 -newkey rsa:4096 -keyout data/assets/ssl-example/key.pem -out data/assets/ssl-example/cert.pem -days 365 -subj "/C=DE/ST=NRW/L=Willich/O=mailcow/OU=mailcow/CN=${MAILCOW_HOSTNAME}" -sha256 -nodes echo "Copying snake-oil certificate..." cp -n -d data/assets/ssl-example/*.pem data/assets/ssl/ + +# Set app_info.inc.php +mailcow_git_version=$(git describe --tags `git rev-list --tags --max-count=1`) +if [ $? -eq 0 ]; then + mailcow_git_url=$(git config --get remote.origin.url) + echo ' data/web/inc/app_info.inc.php + echo ' $MAILCOW_GIT_VERSION="'$mailcow_git_version'";' >> data/web/inc/app_info.inc.php + echo ' $MAILCOW_GIT_URL="'$mailcow_git_url'";' >> data/web/inc/app_info.inc.php + echo '?>' >> data/web/inc/app_info.inc.php +else + echo ' data/web/inc/app_info.inc.php + echo ' $MAILCOW_GIT_VERSION="";' >> data/web/inc/app_info.inc.php + echo ' $MAILCOW_GIT_URL="";' >> data/web/inc/app_info.inc.php + echo '?>' >> data/web/inc/app_info.inc.php + echo -e "\e[33mCannot determine current git repository version...\e[0m" +fi diff --git a/update.sh b/update.sh index 2f03efff..a9291d62 100755 --- a/update.sh +++ b/update.sh @@ -719,6 +719,22 @@ if [ -f "data/conf/rspamd/local.d/metrics.conf" ]; then mv data/conf/rspamd/local.d/metrics.conf data/conf/rspamd/local.d/metrics.conf_deprecated fi +# Set app_info.inc.php +mailcow_git_version=$(git describe --tags `git rev-list --tags --max-count=1`) +if [ $? -eq 0 ]; then + mailcow_git_url=$(git config --get remote.origin.url) + echo ' data/web/inc/app_info.inc.php + echo ' $MAILCOW_GIT_VERSION="'$mailcow_git_version'";' >> data/web/inc/app_info.inc.php + echo ' $MAILCOW_GIT_URL="'$mailcow_git_url'";' >> data/web/inc/app_info.inc.php + echo '?>' >> data/web/inc/app_info.inc.php +else + echo ' data/web/inc/app_info.inc.php + echo ' $MAILCOW_GIT_VERSION="";' >> data/web/inc/app_info.inc.php + echo ' $MAILCOW_GIT_URL="";' >> data/web/inc/app_info.inc.php + echo '?>' >> data/web/inc/app_info.inc.php + echo -e "\e[33mCannot determine current git repository version...\e[0m" +fi + if [[ ${SKIP_START} == "y" ]]; then echo -e "\e[33mNot starting mailcow, please run \"docker-compose up -d --remove-orphans\" to start mailcow.\e[0m" else