From c90d637a48cdac86363e4937bdd787db8bc94c37 Mon Sep 17 00:00:00 2001
From: FreddleSpl0it
Date: Thu, 16 Feb 2023 15:32:53 +0100
Subject: [PATCH 001/378] [Web] redirect to sogo after failed sogo-auth
---
data/web/sogo-auth.php | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/data/web/sogo-auth.php b/data/web/sogo-auth.php
index 40fff5856..c34a60def 100644
--- a/data/web/sogo-auth.php
+++ b/data/web/sogo-auth.php
@@ -65,8 +65,7 @@ elseif (isset($_GET['login'])) {
}
}
}
- header('HTTP/1.0 403 Forbidden');
- echo "Forbidden";
+ header("Location: /SOGo/");
exit;
}
// only check for admin-login on sogo GUI requests
From cfce7086a578bc4d3883527b969d80a3067b00fb Mon Sep 17 00:00:00 2001
From: FreddleSpl0it
Date: Thu, 16 Feb 2023 15:34:47 +0100
Subject: [PATCH 002/378] [Web] few style changes
---
data/web/css/build/013-datatables.css | 3 ---
data/web/css/build/014-mailcow.css | 20 ++++++++++++++++++++
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/data/web/css/build/013-datatables.css b/data/web/css/build/013-datatables.css
index 57e2b6d94..2b19ba24e 100644
--- a/data/web/css/build/013-datatables.css
+++ b/data/web/css/build/013-datatables.css
@@ -8,9 +8,6 @@
.dtr-details {
width: 100%;
}
-.table-striped>tbody>tr:nth-of-type(odd) {
- background-color: #F2F2F2;
-}
td.child>ul>li {
display: flex;
}
diff --git a/data/web/css/build/014-mailcow.css b/data/web/css/build/014-mailcow.css
index 6c70a2a55..8c1d7c2af 100644
--- a/data/web/css/build/014-mailcow.css
+++ b/data/web/css/build/014-mailcow.css
@@ -33,6 +33,13 @@
url('/fonts/noto-sans-v12-latin_greek_cyrillic-700italic.woff2') format('woff2'),
url('/fonts/noto-sans-v12-latin_greek_cyrillic-700italic.woff') format('woff');
}
+
+body {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ background-color: #fbfbfb;
+}
#maxmsgsize { min-width: 80px; }
#slider1 .slider-selection {
background: #FFD700;
@@ -78,6 +85,19 @@
.navbar-fixed-top .navbar-collapse {
max-height: 1000px
}
+.nav-tabs .nav-link, .nav-tabs .nav-link.disabled, .nav-tabs .nav-link.disabled:hover, .nav-tabs .nav-link.disabled:focus {
+ border-color: #dfdfdf;
+}
+.nav-tabs .nav-link.active, .nav-tabs .nav-item.show .nav-link {
+ border-color: #dfdfdf;
+ border-bottom: 1px solid #ffffff;
+}
+.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {
+ border-color: #dfdfdf;
+}
+.nav-tabs {
+ border-bottom: 1px solid #dfdfdf;
+}
.bi {
display: inline-block;
font-size: 12pt;
From 415c1d057499a4f927d4eb4edbca467785fee6a7 Mon Sep 17 00:00:00 2001
From: FreddleSpl0it
Date: Thu, 16 Feb 2023 15:39:12 +0100
Subject: [PATCH 003/378] [Web] add seperate link for logged in users
---
data/web/inc/functions.customize.inc.php | 25 +++++++++--
data/web/inc/header.inc.php | 9 ++++
data/web/js/site/admin.js | 1 +
.../templates/admin/tab-config-customize.twig | 5 ++-
data/web/templates/base.twig | 41 +++++++++++--------
data/web/templates/index.twig | 4 +-
6 files changed, 64 insertions(+), 21 deletions(-)
diff --git a/data/web/inc/functions.customize.inc.php b/data/web/inc/functions.customize.inc.php
index b72923573..c4df924d9 100644
--- a/data/web/inc/functions.customize.inc.php
+++ b/data/web/inc/functions.customize.inc.php
@@ -122,10 +122,14 @@ function customize($_action, $_item, $_data = null) {
case 'app_links':
$apps = (array)$_data['app'];
$links = (array)$_data['href'];
+ $user_links = (array)$_data['user_href'];
$out = array();
- if (count($apps) == count($links)) {
+ if (count($apps) == count($links) && count($apps) == count($user_links)) {
for ($i = 0; $i < count($apps); $i++) {
- $out[] = array($apps[$i] => $links[$i]);
+ $out[] = array($apps[$i] => array(
+ 'link' => $links[$i],
+ 'user_link' => $user_links[$i]
+ ));
}
try {
$redis->set('APP_LINKS', json_encode($out));
@@ -256,7 +260,22 @@ function customize($_action, $_item, $_data = null) {
);
return false;
}
- return ($app_links) ? $app_links : false;
+
+ if (empty($app_links)){
+ return false;
+ }
+
+ foreach($app_links as $key => $value){
+ foreach($value as $app => $details){
+ if (empty($details['user_link']) || empty($_SESSION['mailcow_cc_username'])){
+ $app_links[$key][$app]['user_link'] = $app_links[$key][$app]['link'];
+ } else {
+ $app_links[$key][$app]['user_link'] = str_replace('%u', $_SESSION['mailcow_cc_username'], $app_links[$key][$app]['user_link']);
+ }
+ }
+ }
+
+ return $app_links;
break;
case 'main_logo':
case 'main_logo_dark':
diff --git a/data/web/inc/header.inc.php b/data/web/inc/header.inc.php
index 9afc288dd..c0e166403 100644
--- a/data/web/inc/header.inc.php
+++ b/data/web/inc/header.inc.php
@@ -30,6 +30,14 @@ if(!file_exists($CSSPath)) {
cleanupCSS($hash);
}
+$mailcow_apps_processed = $MAILCOW_APPS;
+for ($i = 0; $i < count($mailcow_apps_processed); $i++) {
+ if (!empty($_SESSION['mailcow_cc_username'])){
+ $mailcow_apps_processed[$i]['user_link'] = str_replace('%u', $_SESSION['mailcow_cc_username'], $mailcow_apps_processed[$i]['user_link']);
+ }
+}
+
+
$globalVariables = [
'mailcow_hostname' => getenv('MAILCOW_HOSTNAME'),
'mailcow_locale' => @$_SESSION['mailcow_locale'],
@@ -45,6 +53,7 @@ $globalVariables = [
'lang' => $lang,
'skip_sogo' => (getenv('SKIP_SOGO') == 'y'),
'allow_admin_email_login' => (getenv('ALLOW_ADMIN_EMAIL_LOGIN') == 'n'),
+ 'mailcow_apps_processed' => $mailcow_apps_processed,
'mailcow_apps' => $MAILCOW_APPS,
'app_links' => customize('get', 'app_links'),
'is_root_uri' => (parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) == '/'),
diff --git a/data/web/js/site/admin.js b/data/web/js/site/admin.js
index 80da64167..095557311 100644
--- a/data/web/js/site/admin.js
+++ b/data/web/js/site/admin.js
@@ -711,6 +711,7 @@ jQuery(function($){
if (type == "app_link") {
cols = ' ';
cols += ' ';
+ cols += ' ';
cols += '' + lang.remove_row + ' ';
} else if (type == "f2b_regex") {
cols = ' ';
diff --git a/data/web/templates/admin/tab-config-customize.twig b/data/web/templates/admin/tab-config-customize.twig
index 7fc990a64..4b8f53231 100644
--- a/data/web/templates/admin/tab-config-customize.twig
+++ b/data/web/templates/admin/tab-config-customize.twig
@@ -58,13 +58,15 @@
{{ lang.admin.app_name }}
{{ lang.admin.link }}
+ {{ lang.admin.user_link }}
{% for row in app_links %}
{% for key, val in row %}
-
+
+
{{ lang.admin.remove_row }}
{% endfor %}
@@ -73,6 +75,7 @@
+
{{ lang.admin.remove_row }}
{% endfor %}
diff --git a/data/web/templates/base.twig b/data/web/templates/base.twig
index ca744d2a3..1c027138c 100644
--- a/data/web/templates/base.twig
+++ b/data/web/templates/base.twig
@@ -29,7 +29,7 @@
{% block navbar %}
-
+
{% endif %}
-
+
{% block content %}{% endblock %}
diff --git a/data/web/templates/index.twig b/data/web/templates/index.twig
index aa282547c..bd4f87818 100644
--- a/data/web/templates/index.twig
+++ b/data/web/templates/index.twig
@@ -77,7 +77,9 @@
{% endfor %}
{% for row in app_links %}
{% for key, val in row %}
-
{{ key }}
+
{% endfor %}
{% endfor %}
From 6e35574c721971216aa10da1ba6ace663ad4ca13 Mon Sep 17 00:00:00 2001
From: FreddleSpl0it
Date: Fri, 10 Mar 2023 15:53:09 +0100
Subject: [PATCH 004/378] [Web] add app hide option
---
data/web/inc/functions.customize.inc.php | 6 +++--
data/web/inc/header.inc.php | 24 +++++++++++++++++--
data/web/inc/vars.inc.php | 4 +++-
data/web/js/site/admin.js | 14 +++++++++++
.../templates/admin/tab-config-customize.twig | 12 ++++++++++
data/web/templates/index.twig | 12 +++++++---
6 files changed, 64 insertions(+), 8 deletions(-)
diff --git a/data/web/inc/functions.customize.inc.php b/data/web/inc/functions.customize.inc.php
index c4df924d9..5aef7d720 100644
--- a/data/web/inc/functions.customize.inc.php
+++ b/data/web/inc/functions.customize.inc.php
@@ -123,12 +123,14 @@ function customize($_action, $_item, $_data = null) {
$apps = (array)$_data['app'];
$links = (array)$_data['href'];
$user_links = (array)$_data['user_href'];
+ $hide = (array)$_data['hide'];
$out = array();
- if (count($apps) == count($links) && count($apps) == count($user_links)) {
+ if (count($apps) == count($links) && count($apps) == count($user_links) && count($apps) == count($hide)) {
for ($i = 0; $i < count($apps); $i++) {
$out[] = array($apps[$i] => array(
'link' => $links[$i],
- 'user_link' => $user_links[$i]
+ 'user_link' => $user_links[$i],
+ 'hide' => ($hide[$i] === '0' || $hide[$i] === 0) ? false : true
));
}
try {
diff --git a/data/web/inc/header.inc.php b/data/web/inc/header.inc.php
index c0e166403..3f80423ec 100644
--- a/data/web/inc/header.inc.php
+++ b/data/web/inc/header.inc.php
@@ -31,11 +31,29 @@ if(!file_exists($CSSPath)) {
}
$mailcow_apps_processed = $MAILCOW_APPS;
+$app_links = customize('get', 'app_links');
+$app_links_processed = $app_links;
+$hide_mailcow_apps = true;
for ($i = 0; $i < count($mailcow_apps_processed); $i++) {
+ if ($hide_mailcow_apps && !$mailcow_apps_processed[$i]['hide']){
+ $hide_mailcow_apps = false;
+ }
if (!empty($_SESSION['mailcow_cc_username'])){
$mailcow_apps_processed[$i]['user_link'] = str_replace('%u', $_SESSION['mailcow_cc_username'], $mailcow_apps_processed[$i]['user_link']);
}
}
+if ($app_links_processed){
+ for ($i = 0; $i < count($app_links_processed); $i++) {
+ $key = array_key_first($app_links_processed[$i]);
+ if ($hide_mailcow_apps && !$app_links_processed[$i][$key]['hide']){
+ $hide_mailcow_apps = false;
+ }
+ if (!empty($_SESSION['mailcow_cc_username'])){
+ $app_links_processed[$i][$key]['user_link'] = str_replace('%u', $_SESSION['mailcow_cc_username'], $app_links_processed[$i][$key]['user_link']);
+ }
+ }
+}
+
$globalVariables = [
@@ -53,9 +71,11 @@ $globalVariables = [
'lang' => $lang,
'skip_sogo' => (getenv('SKIP_SOGO') == 'y'),
'allow_admin_email_login' => (getenv('ALLOW_ADMIN_EMAIL_LOGIN') == 'n'),
- 'mailcow_apps_processed' => $mailcow_apps_processed,
+ 'hide_mailcow_apps' => $hide_mailcow_apps,
'mailcow_apps' => $MAILCOW_APPS,
- 'app_links' => customize('get', 'app_links'),
+ 'mailcow_apps_processed' => $mailcow_apps_processed,
+ 'app_links' => $app_links,
+ 'app_links_processed' => $app_links_processed,
'is_root_uri' => (parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) == '/'),
'uri' => $_SERVER['REQUEST_URI'],
'last_login' => last_login('get', $_SESSION['mailcow_cc_username'], 7, 0)['ui']['time']
diff --git a/data/web/inc/vars.inc.php b/data/web/inc/vars.inc.php
index afc801e44..18bc63285 100644
--- a/data/web/inc/vars.inc.php
+++ b/data/web/inc/vars.inc.php
@@ -122,7 +122,9 @@ $SHOW_DKIM_PRIV_KEYS = false;
$MAILCOW_APPS = array(
array(
'name' => 'Webmail',
- 'link' => '/SOGo/',
+ 'link' => '/SOGo/so/',
+ 'user_link' => '/sogo-auth.php?login=%u',
+ 'hide' => true
)
);
diff --git a/data/web/js/site/admin.js b/data/web/js/site/admin.js
index 095557311..dd6dcce4b 100644
--- a/data/web/js/site/admin.js
+++ b/data/web/js/site/admin.js
@@ -706,20 +706,34 @@ jQuery(function($){
}
})
// App links
+ // setup eventlistener
+ setAppHideEvent();
+ function setAppHideEvent(){
+ $('.app_hide').off('change');
+ $('.app_hide').on('change', function (e) {
+ var value = $(this).is(':checked') ? '1' : '0';
+ console.log(value)
+ $(this).parent().children(':first-child').val(value);
+ })
+ }
function add_table_row(table_id, type) {
var row = $(' ');
if (type == "app_link") {
cols = ' ';
cols += ' ';
cols += ' ';
+ cols += '
';
cols += '' + lang.remove_row + ' ';
} else if (type == "f2b_regex") {
cols = ' ';
cols += ' ';
cols += '' + lang.remove_row + ' ';
}
+
row.append(cols);
table_id.append(row);
+ if (type == "app_link")
+ setAppHideEvent();
}
$('#app_link_table').on('click', 'tr a', function (e) {
e.preventDefault();
diff --git a/data/web/templates/admin/tab-config-customize.twig b/data/web/templates/admin/tab-config-customize.twig
index 4b8f53231..93da2bfdb 100644
--- a/data/web/templates/admin/tab-config-customize.twig
+++ b/data/web/templates/admin/tab-config-customize.twig
@@ -59,6 +59,7 @@
{{ lang.admin.app_name }}
{{ lang.admin.link }}
{{ lang.admin.user_link }}
+ {{ lang.admin.app_hide }}
{% for row in app_links %}
@@ -67,6 +68,12 @@
+
+
+
+
+
+
{{ lang.admin.remove_row }}
{% endfor %}
@@ -76,6 +83,11 @@
+
+
+
+
+
{{ lang.admin.remove_row }}
{% endfor %}
diff --git a/data/web/templates/index.twig b/data/web/templates/index.twig
index bd4f87818..420bd5318 100644
--- a/data/web/templates/index.twig
+++ b/data/web/templates/index.twig
@@ -67,19 +67,25 @@
{{ lang.login.delayed|format(login_delay) }}
{% endif %}
- {% if not oauth2_request and (mailcow_apps or app_links) %}
+ {% if not oauth2_request and (mailcow_apps or app_links) and not hide_mailcow_apps %}
{{ ui_texts.apps_name|raw }}
{% for app in mailcow_apps %}
- {% if not skip_sogo or not is_uri('SOGo', app.link) %}
-
{{ app.name }}
+ {% if not app.hide %}
+ {% if not skip_sogo or not is_uri('SOGo', app.link) %}
+
{% endif %}
+ {% endif %}
{% endfor %}
{% for row in app_links %}
{% for key, val in row %}
+ {% if not val.hide %}
+ {% endif %}
{% endfor %}
{% endfor %}
From 84ff6ff2c5b591bbbc693e22e739e51cff835cca Mon Sep 17 00:00:00 2001
From: FreddleSpl0it
Date: Fri, 10 Mar 2023 15:53:59 +0100
Subject: [PATCH 005/378] [Web] fix user login history
---
data/web/inc/functions.inc.php | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php
index 3cff09b95..ee1aab236 100644
--- a/data/web/inc/functions.inc.php
+++ b/data/web/inc/functions.inc.php
@@ -960,12 +960,16 @@ function check_login($user, $pass, $app_passwd_data = false) {
);
return "pending";
} else if (!isset($authenticators['additional']) || !is_array($authenticators['additional']) || count($authenticators['additional']) == 0) {
+ unset($_SESSION['ldelay']);
// no authenticators found, login successfull
// Reactivate TFA if it was set to "deactivate TFA for next login"
$stmt = $pdo->prepare("UPDATE `tfa` SET `active`='1' WHERE `username` = :user");
$stmt->execute(array(':user' => $user));
-
- unset($_SESSION['ldelay']);
+ $_SESSION['return'][] = array(
+ 'type' => 'success',
+ 'log' => array(__FUNCTION__, $user, '*'),
+ 'msg' => array('logged_in_as', $user)
+ );
return "user";
}
} elseif ($app_passwd_data['eas'] === true || $app_passwd_data['dav'] === true) {
From 56a9f1a4115194c63d37ee8c451c7e432a3291c5 Mon Sep 17 00:00:00 2001
From: FreddleSpl0it
Date: Fri, 10 Mar 2023 17:10:05 +0100
Subject: [PATCH 006/378] [Web] organize user landing
---
data/web/css/build/014-mailcow.css | 1 +
data/web/js/site/user.js | 30 +-
data/web/templates/domainadmin.twig | 141 +++++-----
data/web/templates/user.twig | 1 -
data/web/templates/user/Spamfilter.twig | 8 +-
data/web/templates/user/tab-user-auth.twig | 310 ++++++++++++---------
6 files changed, 271 insertions(+), 220 deletions(-)
diff --git a/data/web/css/build/014-mailcow.css b/data/web/css/build/014-mailcow.css
index 8c1d7c2af..d1d6ac45d 100644
--- a/data/web/css/build/014-mailcow.css
+++ b/data/web/css/build/014-mailcow.css
@@ -386,6 +386,7 @@ button[aria-expanded='true'] > .caret {
background-color: #f0f0f0;
}
.btn.btn-outline-secondary {
+ color: #000000 !important;
border-color: #cfcfcf !important;
}
.btn-check:checked+.btn-outline-secondary, .btn-check:active+.btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show {
diff --git a/data/web/js/site/user.js b/data/web/js/site/user.js
index 088321cd3..850570ef4 100644
--- a/data/web/js/site/user.js
+++ b/data/web/js/site/user.js
@@ -77,11 +77,11 @@ jQuery(function($){
acl_data = JSON.parse(acl);
$('.clear-last-logins').on('click', function () {if (confirm(lang.delete_ays)) {last_logins('reset');}})
- $(".login-history").on('click', function(e) {e.preventDefault(); last_logins('get', $(this).data('days'));$(this).addClass('active').siblings().removeClass('active');});
+ $(".login-history").on('click', function(e) {e.preventDefault(); last_logins('get', $(this).data('days'));$(this).parent().find('li a').removeClass('active');$(this).children(':first-child').addClass('active')});
function last_logins(action, days = 7) {
if (action == 'get') {
- $('.last-login').html(' ' + lang.waiting);
+ $('#spinner-last-login').removeClass('d-none');
$.ajax({
dataType: 'json',
url: '/api/v1/get/last-login/' + encodeURIComponent(mailcow_cc_username) + '/' + days,
@@ -90,26 +90,38 @@ jQuery(function($){
console.log('error reading last logins');
},
success: function (data) {
- $('.last-login').html();
+ $('.last-ui-login').html('');
+ $('.last-sasl-login').html('');
if (data.ui.time) {
- $('.last-login').html(' ' + lang.last_ui_login + ': ' + unix_time_format(data.ui.time));
+ $('.last-ui-login').html(' ' + lang.last_ui_login + ': ' + unix_time_format(data.ui.time));
} else {
- $('.last-login').text(lang.no_last_login);
+ $('.last-ui-login').text(lang.no_last_login);
}
if (data.sasl) {
- $('.last-login').append('');
}
+
+ $('#spinner-last-login').addClass('d-none');
}
})
} else if (action == 'reset') {
diff --git a/data/web/templates/domainadmin.twig b/data/web/templates/domainadmin.twig
index 070bf00cd..9cfd25599 100644
--- a/data/web/templates/domainadmin.twig
+++ b/data/web/templates/domainadmin.twig
@@ -1,80 +1,83 @@
{% extends 'base.twig' %}
{% block content %}
-{{ lang.user.user_settings }}
-
-
-
-
-
+
+
+
+
+
+
+
- {# TFA #}
-
-
{{ lang.tfa.tfa }}
-
-
{{ tfa_data.pretty }}
- {% include 'tfa_keys.twig' %}
-
-
-
-
-
{{ lang.tfa.set_tfa }}
-
-
- {{ lang.tfa.yubi_otp }}
- {{ lang.tfa.webauthn }}
- {{ lang.tfa.totp }}
- {{ lang.tfa.none }}
-
-
-
+ {# TFA #}
+
+
{{ lang.tfa.tfa }}
+
+
{{ tfa_data.pretty }}
+ {% include 'tfa_keys.twig' %}
+
+
+
+
+
{{ lang.tfa.set_tfa }}
+
+
+ {{ lang.tfa.yubi_otp }}
+ {{ lang.tfa.webauthn }}
+ {{ lang.tfa.totp }}
+ {{ lang.tfa.none }}
+
+
+
-
- {# FIDO2 #}
-
-
-
{{ lang.fido2.fido2_auth }}
-
-
-
-
{{ lang.fido2.known_ids }}:
-
-
-
-
- ID
- {{ lang.admin.action }}
-
- {% include 'fido2.twig' %}
-
-
-
-
-
-
-
-
-
{{ lang.fido2.set_fido2 }}
-
-
+
+ {# FIDO2 #}
+
+
+
{{ lang.fido2.fido2_auth }}
+
+
+
+
{{ lang.fido2.known_ids }}:
+
+
+
+
+ ID
+ {{ lang.admin.action }}
+
+ {% include 'fido2.twig' %}
+
+
+
-
-
-
-
{{ lang.fido2.register_status }}:
-
-
-
+
+
+
+ {{ lang.fido2.set_fido2 }}
+
+
+
+
+
+
+
+
{{ lang.fido2.register_status }}:
+
+
+
-
diff --git a/data/web/templates/user.twig b/data/web/templates/user.twig
index 5536abe4e..a79c5a2c5 100644
--- a/data/web/templates/user.twig
+++ b/data/web/templates/user.twig
@@ -43,7 +43,6 @@
-
{% include 'user_domainadmin_common.twig' %}
{% endblock %}
diff --git a/data/web/templates/user/Spamfilter.twig b/data/web/templates/user/Spamfilter.twig
index 280b90032..1f69df95f 100644
--- a/data/web/templates/user/Spamfilter.twig
+++ b/data/web/templates/user/Spamfilter.twig
@@ -39,10 +39,10 @@
-
+
{{ lang.user.spamfilter_wl }}
{{ lang.user.spamfilter_wl_desc|raw }}
-
-
+
{{ lang.user.spamfilter_bl }}
{{ lang.user.spamfilter_bl_desc|raw }}
-