From aca01c8aa2607777205226a86be29df338eb51d9 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Mon, 27 Jan 2025 15:59:50 +0100 Subject: [PATCH] [Web] Separate Login pages --- data/web/{debug.php => admin/dashboard.php} | 17 +- data/web/admin/index.php | 29 ++ data/web/{ => admin}/mailbox.php | 16 +- data/web/{ => admin}/queue.php | 15 +- data/web/{admin.php => admin/system.php} | 13 +- data/web/css/site/admin.css | 3 - data/web/domainadmin/index.php | 28 ++ data/web/domainadmin/mailbox.php | 58 ++++ data/web/domainadmin/user.php | 44 +++ data/web/inc/functions.inc.php | 1 + data/web/inc/init_db.inc.php | 2 +- data/web/inc/prerequisites.inc.php | 2 +- data/web/inc/sessions.inc.php | 19 +- data/web/inc/triggers.admin.inc.php | 93 +++++++ data/web/inc/triggers.domainadmin.inc.php | 62 +++++ data/web/inc/triggers.global.inc.php | 48 ++++ data/web/inc/triggers.inc.php | 263 ------------------ data/web/inc/triggers.user.inc.php | 132 +++++++++ data/web/index.php | 19 +- data/web/js/site/{debug.js => dashboard.js} | 0 data/web/js/site/mailbox.js | 2 +- data/web/reset-password.php | 4 +- data/web/templates/admin_index.twig | 91 ++++++ data/web/templates/base.twig | 43 +-- .../templates/{debug.twig => dashboard.twig} | 4 +- data/web/templates/domainadmin_index.twig | 91 ++++++ data/web/templates/user/tab-user-auth.twig | 4 +- .../templates/{index.twig => user_index.twig} | 0 data/web/user.php | 33 +-- 29 files changed, 798 insertions(+), 338 deletions(-) rename data/web/{debug.php => admin/dashboard.php} (83%) create mode 100644 data/web/admin/index.php rename data/web/{ => admin}/mailbox.php (73%) rename data/web/{ => admin}/queue.php (55%) rename data/web/{admin.php => admin/system.php} (90%) create mode 100644 data/web/domainadmin/index.php create mode 100644 data/web/domainadmin/mailbox.php create mode 100644 data/web/domainadmin/user.php create mode 100644 data/web/inc/triggers.admin.inc.php create mode 100644 data/web/inc/triggers.domainadmin.inc.php create mode 100644 data/web/inc/triggers.global.inc.php delete mode 100644 data/web/inc/triggers.inc.php create mode 100644 data/web/inc/triggers.user.inc.php rename data/web/js/site/{debug.js => dashboard.js} (100%) create mode 100644 data/web/templates/admin_index.twig rename data/web/templates/{debug.twig => dashboard.twig} (99%) create mode 100644 data/web/templates/domainadmin_index.twig rename data/web/templates/{index.twig => user_index.twig} (100%) diff --git a/data/web/debug.php b/data/web/admin/dashboard.php similarity index 83% rename from data/web/debug.php rename to data/web/admin/dashboard.php index 4a099cb6e..894b1c645 100644 --- a/data/web/debug.php +++ b/data/web/admin/dashboard.php @@ -1,8 +1,17 @@ Get('LICENSE_STATUS_CAC $_SESSION['gal'] = json_decode($license_cache, true); } -$js_minifier->add('/web/js/site/debug.js'); +$js_minifier->add('/web/js/site/dashboard.js'); // vmail df $exec_fields = array('cmd' => 'system', 'task' => 'df', 'dir' => '/var/vmail'); @@ -61,7 +70,7 @@ foreach ($containers_info as $container => $container_info) { $hostname = getenv('MAILCOW_HOSTNAME'); $timezone = getenv('TZ'); -$template = 'debug.twig'; +$template = 'dashboard.twig'; $template_data = [ 'log_lines' => getenv('LOG_LINES'), 'vmail_df' => $vmail_df, diff --git a/data/web/admin/index.php b/data/web/admin/index.php new file mode 100644 index 000000000..05ba70337 --- /dev/null +++ b/data/web/admin/index.php @@ -0,0 +1,29 @@ + @$_SESSION['ldelay'] +]; + +$js_minifier->add('/web/js/site/index.js'); +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; diff --git a/data/web/mailbox.php b/data/web/admin/mailbox.php similarity index 73% rename from data/web/mailbox.php rename to data/web/admin/mailbox.php index a84e32c47..d0073bbd6 100644 --- a/data/web/mailbox.php +++ b/data/web/admin/mailbox.php @@ -1,10 +1,20 @@ add('/web/js/site/mailbox.js'); $js_minifier->add('/web/js/presets/sieveMailbox.js'); $js_minifier->add('/web/js/site/pwgen.js'); -$role = ($_SESSION['mailcow_cc_role'] == "admin") ? 'admin' : 'domainadmin'; +$role = "admin"; $is_dual = (!empty($_SESSION["dual-login"]["username"])) ? 'true' : 'false'; $allow_admin_email_login = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["ALLOW_ADMIN_EMAIL_LOGIN"])) ? 'true' : 'false'; diff --git a/data/web/queue.php b/data/web/admin/queue.php similarity index 55% rename from data/web/queue.php rename to data/web/admin/queue.php index ffce8d8b0..85ec59401 100644 --- a/data/web/queue.php +++ b/data/web/admin/queue.php @@ -1,8 +1,17 @@ add('/web/js/site/queue.js'); $_SESSION['return_to'] = $_SERVER['REQUEST_URI']; -$role = ($_SESSION['mailcow_cc_role'] == "admin") ? 'admin' : 'domainadmin'; +$role = "admin"; $template = 'queue.twig'; $template_data = [ diff --git a/data/web/admin.php b/data/web/admin/system.php similarity index 90% rename from data/web/admin.php rename to data/web/admin/system.php index 5a8895dee..c21d43f0d 100644 --- a/data/web/admin.php +++ b/data/web/admin/system.php @@ -1,8 +1,17 @@ thead > tr > th, .table-condensed > tbody > tr > th, .table-condensed > tfoot > tr > th, .table-condensed > thead > tr > td, .table-condensed > tbody > tr > td, .table-condensed > tfoot > tr > td { padding: 3px; } -table tbody tr { - cursor: pointer; -} table tbody tr td input[type="checkbox"] { cursor: pointer; } diff --git a/data/web/domainadmin/index.php b/data/web/domainadmin/index.php new file mode 100644 index 000000000..2d909f97f --- /dev/null +++ b/data/web/domainadmin/index.php @@ -0,0 +1,28 @@ + @$_SESSION['ldelay'], +]; + +$js_minifier->add('/web/js/site/index.js'); +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; diff --git a/data/web/domainadmin/mailbox.php b/data/web/domainadmin/mailbox.php new file mode 100644 index 000000000..bb2ef16f3 --- /dev/null +++ b/data/web/domainadmin/mailbox.php @@ -0,0 +1,58 @@ +add('/web/js/site/mailbox.js'); +$js_minifier->add('/web/js/presets/sieveMailbox.js'); +$js_minifier->add('/web/js/site/pwgen.js'); + +$role = "domainadmin"; +$is_dual = (!empty($_SESSION["dual-login"]["username"])) ? 'true' : 'false'; +$allow_admin_email_login = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["ALLOW_ADMIN_EMAIL_LOGIN"])) ? 'true' : 'false'; + +// domains +$domains = mailbox('get', 'domains'); + +// mailboxes +$mailboxes = []; +foreach ($domains as $domain) { + foreach (mailbox('get', 'mailboxes', $domain) as $mailbox) { + $mailboxes[] = $mailbox; + } +} + +$template = 'mailbox.twig'; +$template_data = [ + 'acl' => $_SESSION['acl'], + 'acl_json' => json_encode($_SESSION['acl']), + 'role' => $role, + 'is_dual' => $is_dual, + 'allow_admin_email_login' => $allow_admin_email_login, + 'global_filters' => mailbox('get', 'global_filter_details'), + 'domains' => $domains, + 'mailboxes' => $mailboxes, + 'lang_mailbox' => json_encode($lang['mailbox']), + 'lang_rl' => json_encode($lang['ratelimit']), + 'lang_edit' => json_encode($lang['edit']), + 'lang_datatables' => json_encode($lang['datatables']), +]; + +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; \ No newline at end of file diff --git a/data/web/domainadmin/user.php b/data/web/domainadmin/user.php new file mode 100644 index 000000000..7f1b392e0 --- /dev/null +++ b/data/web/domainadmin/user.php @@ -0,0 +1,44 @@ + "get_friendly_names")); + $username = $_SESSION['mailcow_cc_username']; + + $template = 'domainadmin.twig'; + $template_data = [ + 'acl' => $_SESSION['acl'], + 'acl_json' => json_encode($_SESSION['acl']), + 'user_spam_score' => mailbox('get', 'spam_score', $username), + 'tfa_data' => $tfa_data, + 'fido2_data' => $fido2_data, + 'lang_user' => json_encode($lang['user']), + 'lang_datatables' => json_encode($lang['datatables']), + ]; +} +elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'admin') { + header('Location: /admin/dashboard'); + exit(); +} +elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') { + header('Location: /user'); + exit(); +} +else { + header('Location: /domainadmin'); + exit(); +} + +$js_minifier->add('/web/js/site/user.js'); +$js_minifier->add('/web/js/site/pwgen.js'); + +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index ed41379f4..233624278 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -3101,6 +3101,7 @@ function clear_session(){ session_write_close(); } function set_user_loggedin_session($user) { + session_regenerate_id(true); $_SESSION['mailcow_cc_username'] = $user; $_SESSION['mailcow_cc_role'] = 'user'; $sogo_sso_pass = file_get_contents("/etc/sogo-sso/sogo-sso.pass"); diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index 7fb619d44..156856c24 100644 --- a/data/web/inc/init_db.inc.php +++ b/data/web/inc/init_db.inc.php @@ -3,7 +3,7 @@ function init_db_schema() { try { global $pdo; - $db_version = "20112024_1105"; + $db_version = "27012025_1555"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); diff --git a/data/web/inc/prerequisites.inc.php b/data/web/inc/prerequisites.inc.php index 5738e7c0a..deb5da8fa 100644 --- a/data/web/inc/prerequisites.inc.php +++ b/data/web/inc/prerequisites.inc.php @@ -297,7 +297,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.rspamd.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.tls_policy_maps.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.transports.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/init_db.inc.php'; -require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.inc.php'; +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.global.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/twig.inc.php'; init_db_schema(); if (isset($_SESSION['mailcow_cc_role'])) { diff --git a/data/web/inc/sessions.inc.php b/data/web/inc/sessions.inc.php index 67bdd35b3..bbc08cf13 100644 --- a/data/web/inc/sessions.inc.php +++ b/data/web/inc/sessions.inc.php @@ -99,15 +99,30 @@ if (isset($_POST["logout"])) { unset($_SESSION['sogo-sso-user-allowed']); unset($_SESSION['sogo-sso-pass']); unset($_SESSION["dual-login"]); - header("Location: /mailbox"); + if ($_SESSION["mailcow_cc_role"] == "admin"){ + header("Location: /admin/mailbox"); + } elseif ($_SESSION["mailcow_cc_role"] == "domainadmin") { + header("Location: /domainadmin/mailbox"); + } else { + header("Location: /"); + } exit(); } else { + $role = $_SESSION["mailcow_cc_role"]; session_regenerate_id(true); session_unset(); session_destroy(); session_write_close(); - header("Location: /"); + if ($role == "admin") { + header("Location: /admin"); + } + elseif ($role == "domainadmin") { + header("Location: /domainadmin"); + } + else { + header("Location: /"); + } } } diff --git a/data/web/inc/triggers.admin.inc.php b/data/web/inc/triggers.admin.inc.php new file mode 100644 index 000000000..5b1061f7e --- /dev/null +++ b/data/web/inc/triggers.admin.inc.php @@ -0,0 +1,93 @@ + "admin")); + + if ($as == "admin") { + session_regenerate_id(true); + $_SESSION['mailcow_cc_username'] = $login_user; + $_SESSION['mailcow_cc_role'] = "admin"; + header("Location: /admin/dashboard"); + die(); + } + elseif ($as != "pending") { + unset($_SESSION['pending_mailcow_cc_username']); + unset($_SESSION['pending_mailcow_cc_role']); + unset($_SESSION['pending_tfa_methods']); + unset($_SESSION['mailcow_cc_username']); + unset($_SESSION['mailcow_cc_role']); + } +} + +if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admin" && !isset($_SESSION['mailcow_cc_api'])) { + // TODO: Move file upload to API? + if (isset($_POST["submit_main_logo"])) { + if ($_FILES['main_logo']['error'] == 0) { + customize('add', 'main_logo', $_FILES); + } + if ($_FILES['main_logo_dark']['error'] == 0) { + customize('add', 'main_logo_dark', $_FILES); + } + } + if (isset($_POST["reset_main_logo"])) { + customize('delete', 'main_logo'); + customize('delete', 'main_logo_dark'); + } + // Some actions will not be available via API + if (isset($_POST["license_validate_now"])) { + license('verify'); + } + if (isset($_POST["admin_api"])) { + if (isset($_POST["admin_api"]["ro"])) { + admin_api('ro', 'edit', $_POST); + } + elseif (isset($_POST["admin_api"]["rw"])) { + admin_api('rw', 'edit', $_POST); + } + } + if (isset($_POST["admin_api_regen_key"])) { + if (isset($_POST["admin_api_regen_key"]["ro"])) { + admin_api('ro', 'regen_key', $_POST); + } + elseif (isset($_POST["admin_api_regen_key"]["rw"])) { + admin_api('rw', 'regen_key', $_POST); + } + } + if (isset($_POST["rspamd_ui"])) { + rspamd_ui('edit', $_POST); + } + if (isset($_POST["mass_send"])) { + sys_mail($_POST); + } +} +?> diff --git a/data/web/inc/triggers.domainadmin.inc.php b/data/web/inc/triggers.domainadmin.inc.php new file mode 100644 index 000000000..9ee53d67a --- /dev/null +++ b/data/web/inc/triggers.domainadmin.inc.php @@ -0,0 +1,62 @@ + "domain_admin")); + + if ($as == "domainadmin") { + session_regenerate_id(true); + $_SESSION['mailcow_cc_username'] = $login_user; + $_SESSION['mailcow_cc_role'] = "domainadmin"; + header("Location: /domainadmin/mailbox"); + die(); + } + elseif ($as != "pending") { + unset($_SESSION['pending_mailcow_cc_username']); + unset($_SESSION['pending_mailcow_cc_role']); + unset($_SESSION['pending_tfa_methods']); + unset($_SESSION['mailcow_cc_username']); + unset($_SESSION['mailcow_cc_role']); + } +} +?> diff --git a/data/web/inc/triggers.global.inc.php b/data/web/inc/triggers.global.inc.php new file mode 100644 index 000000000..dd88fad56 --- /dev/null +++ b/data/web/inc/triggers.global.inc.php @@ -0,0 +1,48 @@ + "unset_fido2_key", "post_data" => $_POST)); + } +} +?> diff --git a/data/web/inc/triggers.inc.php b/data/web/inc/triggers.inc.php deleted file mode 100644 index b0c2237d6..000000000 --- a/data/web/inc/triggers.inc.php +++ /dev/null @@ -1,263 +0,0 @@ - $_POST['new_password'], - 'new_password2' => $_POST['new_password2'], - 'token' => $_POST['token'], - 'username' => $username, - 'check_tfa' => True - )); - - if ($reset_result){ - header("Location: /"); - exit; - } -} -if (isset($_POST["verify_tfa_login"])) { - if (verify_tfa_login($_SESSION['pending_mailcow_cc_username'], $_POST)) { - if ($_SESSION['pending_mailcow_cc_role'] == "admin") { - $_SESSION['mailcow_cc_username'] = $_SESSION['pending_mailcow_cc_username']; - $_SESSION['mailcow_cc_role'] = "admin"; - unset($_SESSION['pending_mailcow_cc_username']); - unset($_SESSION['pending_mailcow_cc_role']); - unset($_SESSION['pending_tfa_methods']); - - header("Location: /debug"); - die(); - } - elseif ($_SESSION['pending_mailcow_cc_role'] == "domainadmin") { - $_SESSION['mailcow_cc_username'] = $_SESSION['pending_mailcow_cc_username']; - $_SESSION['mailcow_cc_role'] = "domainadmin"; - unset($_SESSION['pending_mailcow_cc_username']); - unset($_SESSION['pending_mailcow_cc_role']); - unset($_SESSION['pending_tfa_methods']); - - header("Location: /mailbox"); - die(); - } - elseif ($_SESSION['pending_mailcow_cc_role'] == "user") { - if (isset($_SESSION['pending_pw_reset_token']) && isset($_SESSION['pending_pw_new_password'])) { - reset_password("reset", array( - 'new_password' => $_SESSION['pending_pw_new_password'], - 'new_password2' => $_SESSION['pending_pw_new_password'], - 'token' => $_SESSION['pending_pw_reset_token'], - 'username' => $_SESSION['pending_mailcow_cc_username'] - )); - unset($_SESSION['pending_pw_reset_token']); - unset($_SESSION['pending_pw_new_password']); - unset($_SESSION['pending_mailcow_cc_username']); - unset($_SESSION['pending_tfa_methods']); - - header("Location: /"); - die(); - } else { - set_user_loggedin_session($_SESSION['pending_mailcow_cc_username']); - $user_details = mailbox("get", "mailbox_details", $_SESSION['mailcow_cc_username']); - $is_dual = (!empty($_SESSION["dual-login"]["username"])) ? true : false; - if (intval($user_details['attributes']['sogo_access']) == 1 && !$is_dual) { - header("Location: /SOGo/so/{$_SESSION['mailcow_cc_username']}"); - die(); - } else { - header("Location: /user"); - die(); - } - } - } - } - - unset($_SESSION['pending_mailcow_cc_username']); - unset($_SESSION['pending_mailcow_cc_role']); - unset($_SESSION['pending_tfa_methods']); -} - -if (isset($_GET["cancel_tfa_login"])) { - unset($_SESSION['pending_pw_reset_token']); - unset($_SESSION['pending_pw_new_password']); - unset($_SESSION['pending_mailcow_cc_username']); - unset($_SESSION['pending_mailcow_cc_role']); - unset($_SESSION['pending_tfa_methods']); - - header("Location: /"); -} - -if (isset($_POST["quick_release"])) { - quarantine('quick_release', $_POST["quick_release"]); -} - -if (isset($_POST["quick_delete"])) { - quarantine('quick_delete', $_POST["quick_delete"]); -} - -if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) { - $login_user = strtolower(trim($_POST["login_user"])); - $as = check_login($login_user, $_POST["pass_user"]); - - if ($as == "admin") { - $_SESSION['mailcow_cc_username'] = $login_user; - $_SESSION['mailcow_cc_role'] = "admin"; - header("Location: /debug"); - die(); - } - elseif ($as == "domainadmin") { - $_SESSION['mailcow_cc_username'] = $login_user; - $_SESSION['mailcow_cc_role'] = "domainadmin"; - header("Location: /mailbox"); - die(); - } - elseif ($as == "user") { - set_user_loggedin_session($login_user); - $http_parameters = explode('&', $_SESSION['index_query_string']); - unset($_SESSION['index_query_string']); - if (in_array('mobileconfig', $http_parameters)) { - if (in_array('only_email', $http_parameters)) { - header("Location: /mobileconfig.php?only_email"); - die(); - } - header("Location: /mobileconfig.php"); - die(); - } - - $user_details = mailbox("get", "mailbox_details", $login_user); - $is_dual = (!empty($_SESSION["dual-login"]["username"])) ? true : false; - if (intval($user_details['attributes']['sogo_access']) == 1 && !$is_dual) { - header("Location: /SOGo/so/{$login_user}"); - die(); - } else { - header("Location: /user"); - die(); - } - } - elseif ($as != "pending") { - unset($_SESSION['pending_mailcow_cc_username']); - unset($_SESSION['pending_mailcow_cc_role']); - unset($_SESSION['pending_tfa_methods']); - unset($_SESSION['mailcow_cc_username']); - unset($_SESSION['mailcow_cc_role']); - } -} - -if (isset($_SESSION['mailcow_cc_role']) && (isset($_SESSION['acl']['login_as']) && $_SESSION['acl']['login_as'] == "1")) { - if (isset($_GET["duallogin"])) { - $is_dual = (!empty($_SESSION["dual-login"]["username"])) ? true : false; - if (!$is_dual) { - $duallogin = html_entity_decode(rawurldecode($_GET["duallogin"])); - if (filter_var($duallogin, FILTER_VALIDATE_EMAIL)) { - if (!empty(mailbox('get', 'mailbox_details', $duallogin))) { - $_SESSION["dual-login"]["username"] = $_SESSION['mailcow_cc_username']; - $_SESSION["dual-login"]["role"] = $_SESSION['mailcow_cc_role']; - $_SESSION['mailcow_cc_username'] = $duallogin; - $_SESSION['mailcow_cc_role'] = "user"; - header("Location: /user"); - } - } - else { - if (!empty(domain_admin('details', $duallogin))) { - $_SESSION["dual-login"]["username"] = $_SESSION['mailcow_cc_username']; - $_SESSION["dual-login"]["role"] = $_SESSION['mailcow_cc_role']; - $_SESSION['mailcow_cc_username'] = $duallogin; - $_SESSION['mailcow_cc_role'] = "domainadmin"; - header("Location: /user"); - } - } - } - } -} - -if (isset($_SESSION['mailcow_cc_role'])) { - if (isset($_POST["set_tfa"])) { - set_tfa($_POST); - } - if (isset($_POST["unset_tfa_key"])) { - unset_tfa_key($_POST); - } - if (isset($_POST["unset_fido2_key"])) { - fido2(array("action" => "unset_fido2_key", "post_data" => $_POST)); - } -} -if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admin" && !isset($_SESSION['mailcow_cc_api'])) { - // TODO: Move file upload to API? - if (isset($_POST["submit_main_logo"])) { - if ($_FILES['main_logo']['error'] == 0) { - customize('add', 'main_logo', $_FILES); - } - if ($_FILES['main_logo_dark']['error'] == 0) { - customize('add', 'main_logo_dark', $_FILES); - } - } - if (isset($_POST["reset_main_logo"])) { - customize('delete', 'main_logo'); - customize('delete', 'main_logo_dark'); - } - // Some actions will not be available via API - if (isset($_POST["license_validate_now"])) { - license('verify'); - } - if (isset($_POST["admin_api"])) { - if (isset($_POST["admin_api"]["ro"])) { - admin_api('ro', 'edit', $_POST); - } - elseif (isset($_POST["admin_api"]["rw"])) { - admin_api('rw', 'edit', $_POST); - } - } - if (isset($_POST["admin_api_regen_key"])) { - if (isset($_POST["admin_api_regen_key"]["ro"])) { - admin_api('ro', 'regen_key', $_POST); - } - elseif (isset($_POST["admin_api_regen_key"]["rw"])) { - admin_api('rw', 'regen_key', $_POST); - } - } - if (isset($_POST["rspamd_ui"])) { - rspamd_ui('edit', $_POST); - } - if (isset($_POST["mass_send"])) { - sys_mail($_POST); - } -} -?> diff --git a/data/web/inc/triggers.user.inc.php b/data/web/inc/triggers.user.inc.php new file mode 100644 index 000000000..c16edc10e --- /dev/null +++ b/data/web/inc/triggers.user.inc.php @@ -0,0 +1,132 @@ + $_POST['new_password'], + 'new_password2' => $_POST['new_password2'], + 'token' => $_POST['token'], + 'username' => $username, + 'check_tfa' => True + )); + + if ($reset_result){ + header("Location: /"); + exit; + } +} +if (isset($_POST["verify_tfa_login"])) { + if (verify_tfa_login($_SESSION['pending_mailcow_cc_username'], $_POST)) { + if ($_SESSION['pending_mailcow_cc_role'] == "user") { + if (isset($_SESSION['pending_pw_reset_token']) && isset($_SESSION['pending_pw_new_password'])) { + reset_password("reset", array( + 'new_password' => $_SESSION['pending_pw_new_password'], + 'new_password2' => $_SESSION['pending_pw_new_password'], + 'token' => $_SESSION['pending_pw_reset_token'], + 'username' => $_SESSION['pending_mailcow_cc_username'] + )); + unset($_SESSION['pending_pw_reset_token']); + unset($_SESSION['pending_pw_new_password']); + unset($_SESSION['pending_mailcow_cc_username']); + unset($_SESSION['pending_tfa_methods']); + + header("Location: /"); + die(); + } else { + set_user_loggedin_session($_SESSION['pending_mailcow_cc_username']); + $user_details = mailbox("get", "mailbox_details", $_SESSION['mailcow_cc_username']); + $is_dual = (!empty($_SESSION["dual-login"]["username"])) ? true : false; + if (intval($user_details['attributes']['sogo_access']) == 1 && !$is_dual) { + header("Location: /SOGo/so/{$_SESSION['mailcow_cc_username']}"); + die(); + } else { + header("Location: /user"); + die(); + } + } + } + } + + unset($_SESSION['pending_mailcow_cc_username']); + unset($_SESSION['pending_mailcow_cc_role']); + unset($_SESSION['pending_tfa_methods']); +} + +if (isset($_GET["cancel_tfa_login"])) { + unset($_SESSION['pending_pw_reset_token']); + unset($_SESSION['pending_pw_new_password']); + unset($_SESSION['pending_mailcow_cc_username']); + unset($_SESSION['pending_mailcow_cc_role']); + unset($_SESSION['pending_tfa_methods']); + + header("Location: /"); +} + +if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) { + $login_user = strtolower(trim($_POST["login_user"])); + $as = check_login($login_user, $_POST["pass_user"], false, array("role" => "user")); + + if ($as == "user") { + set_user_loggedin_session($login_user); + $http_parameters = explode('&', $_SESSION['index_query_string']); + unset($_SESSION['index_query_string']); + if (in_array('mobileconfig', $http_parameters)) { + if (in_array('only_email', $http_parameters)) { + header("Location: /mobileconfig.php?only_email"); + die(); + } + header("Location: /mobileconfig.php"); + die(); + } + + $user_details = mailbox("get", "mailbox_details", $login_user); + $is_dual = (!empty($_SESSION["dual-login"]["username"])) ? true : false; + if (intval($user_details['attributes']['sogo_access']) == 1 && !$is_dual) { + header("Location: /SOGo/so/{$login_user}"); + die(); + } else { + header("Location: /user"); + die(); + } + } + elseif ($as != "pending") { + unset($_SESSION['pending_mailcow_cc_username']); + unset($_SESSION['pending_mailcow_cc_role']); + unset($_SESSION['pending_tfa_methods']); + unset($_SESSION['mailcow_cc_username']); + unset($_SESSION['mailcow_cc_role']); + } +} +?> diff --git a/data/web/index.php b/data/web/index.php index 0282e4835..1e91cb785 100644 --- a/data/web/index.php +++ b/data/web/index.php @@ -1,5 +1,6 @@ @$_SESSION['oauth2_request'], 'is_mobileconfig' => str_contains($_SESSION['index_query_string'], 'mobileconfig'), diff --git a/data/web/js/site/debug.js b/data/web/js/site/dashboard.js similarity index 100% rename from data/web/js/site/debug.js rename to data/web/js/site/dashboard.js diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index 0c9ffb3d4..3c21c18b0 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -939,7 +939,7 @@ jQuery(function($){ ' ' + lang.remove + '' + ' Login'; if (ALLOW_ADMIN_EMAIL_LOGIN) { - item.action += ' SOGo'; + item.action += ' SOGo'; } item.action += ''; } diff --git a/data/web/reset-password.php b/data/web/reset-password.php index a0225dc6a..7544d40c3 100644 --- a/data/web/reset-password.php +++ b/data/web/reset-password.php @@ -2,11 +2,11 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php'; if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'admin') { - header('Location: /debug'); + header('Location: /admin/dashboard'); exit(); } elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'domainadmin') { - header('Location: /mailbox'); + header('Location: /domainadmin/mailbox'); exit(); } elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') { diff --git a/data/web/templates/admin_index.twig b/data/web/templates/admin_index.twig new file mode 100644 index 000000000..4127a6a21 --- /dev/null +++ b/data/web/templates/admin_index.twig @@ -0,0 +1,91 @@ +{% extends 'base.twig' %} + +{% block navbar %}{% endblock %} + +{% block content %} +
+
+
+
+ {{ lang.login.login }} +
+ + +
+
+
+ + {% if ui_texts.ui_announcement_text and ui_texts.ui_announcement_active %} +
{{ ui_texts.ui_announcement_text|rot13 }}
+ {% endif %} +
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+
+ + +
+
+
+
{{ lang.login.other_logins }}
+ + {% if login_delay %} +

{{ lang.login.delayed|format(login_delay) }}

+ {% endif %} +
+ {% if (mailcow_apps or app_links) and not hide_mailcow_apps %} + {{ ui_texts.apps_name|raw }}
+
+ {% for app in mailcow_apps %} + {% 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 %} +
+ {{ key }} +
+ {% endif %} + {% endfor %} + {% endfor %} +
+ {% endif %} +
+
+
+
+{% endblock %} diff --git a/data/web/templates/base.twig b/data/web/templates/base.twig index 2634574d8..4d0a30251 100644 --- a/data/web/templates/base.twig +++ b/data/web/templates/base.twig @@ -66,27 +66,36 @@ + {% endif %} - {% if mailcow_cc_role != 'admin' %} + {% if mailcow_cc_role == 'domainadmin' %} + + {% elseif mailcow_cc_role == 'user' %} {% endif %} - {% if mailcow_cc_role == 'admin' or mailcow_cc_role == 'domainadmin' %} + {% if mailcow_cc_role == 'domainadmin' %} {% endif %} @@ -246,7 +255,7 @@ function recursiveBase64StrToArrayBuffer(obj) { $(".totp-authenticator-selection").click(function(){ $(".totp-authenticator-selection").removeClass("active"); $(this).addClass("active"); - + var id = $(this).children('input').first().val(); $("#totp_selected_id").val(id); @@ -255,7 +264,7 @@ function recursiveBase64StrToArrayBuffer(obj) { if ($('.totp-authenticator-selection').length == 1 && $('#pending_tfa_tab_yubi_otp').length == 0 && $('.webauthn-authenticator-selection').length == 0){ - + // select default if only one authenticator exists $('.totp-authenticator-selection').addClass("active"); @@ -268,7 +277,7 @@ function recursiveBase64StrToArrayBuffer(obj) { $('#pending_tfa_tab_totp').on('shown.bs.tab', function() { // autofocus setTimeout(function() { $("#collapseTotpTFA").find('input[name="token"]').focus(); }, 200); - }); + }); // validate Yubi OTP tfa if ($('.webauthn-authenticator-selection').length == 0){ // autofocus @@ -287,10 +296,10 @@ function recursiveBase64StrToArrayBuffer(obj) { $(".webauthn-authenticator-selection").click(function(){ $(".webauthn-authenticator-selection").removeClass("active"); $(this).addClass("active"); - + var id = $(this).children('input').first().val(); $("#webauthn_selected_id").val(id); - + var webauthn_status_auth = document.getElementById('webauthn_status_auth'); webauthn_status_auth.style.setProperty('display', 'flex', 'important'); var webauthn_return_code = document.getElementById('webauthn_return_code'); @@ -313,7 +322,7 @@ function recursiveBase64StrToArrayBuffer(obj) { console.log(json); if (json.success === false) throw new Error(); if (json.type === "error") throw new Error(json.msg); - + recursiveBase64StrToArrayBuffer(json); return json; }).then(getCredentialArgs => { @@ -340,7 +349,7 @@ function recursiveBase64StrToArrayBuffer(obj) { webauthn_return_code.style.setProperty('display', 'block', 'important'); webauthn_return_code.innerHTML = lang_tfa.error_code + ': ' + err + ' ' + lang_tfa.reload_retry; }); - } + } }); $('#ConfirmTFAModal').on('hidden.bs.modal', function(){ // cancel pending login @@ -551,7 +560,7 @@ function recursiveBase64StrToArrayBuffer(obj) { Version: {{ mailcow_info.version_tag }} - {% endif %} + {% endif %} {% if mailcow_cc_username and mailcow_info.mailcow_branch|lower == "nightly" and mailcow_info.version_tag|default %} 🛠️🐮 + 🐋 = 💕 diff --git a/data/web/templates/debug.twig b/data/web/templates/dashboard.twig similarity index 99% rename from data/web/templates/debug.twig rename to data/web/templates/dashboard.twig index c148856cb..8f8c2d99f 100644 --- a/data/web/templates/debug.twig +++ b/data/web/templates/dashboard.twig @@ -42,8 +42,8 @@ mailcow-logo-dark
-
- +
+
diff --git a/data/web/templates/domainadmin_index.twig b/data/web/templates/domainadmin_index.twig new file mode 100644 index 000000000..4127a6a21 --- /dev/null +++ b/data/web/templates/domainadmin_index.twig @@ -0,0 +1,91 @@ +{% extends 'base.twig' %} + +{% block navbar %}{% endblock %} + +{% block content %} +
+
+
+
+ {{ lang.login.login }} +
+ + +
+
+
+ + {% if ui_texts.ui_announcement_text and ui_texts.ui_announcement_active %} +
{{ ui_texts.ui_announcement_text|rot13 }}
+ {% endif %} +
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+
+ + +
+
+ +
{{ lang.login.other_logins }}
+ + {% if login_delay %} +

{{ lang.login.delayed|format(login_delay) }}

+ {% endif %} +
+ {% if (mailcow_apps or app_links) and not hide_mailcow_apps %} + {{ ui_texts.apps_name|raw }}
+
+ {% for app in mailcow_apps %} + {% 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 %} +
+ {{ key }} +
+ {% endif %} + {% endfor %} + {% endfor %} +
+ {% endif %} +
+
+
+
+{% endblock %} diff --git a/data/web/templates/user/tab-user-auth.twig b/data/web/templates/user/tab-user-auth.twig index 5c90bedf5..a7e025431 100644 --- a/data/web/templates/user/tab-user-auth.twig +++ b/data/web/templates/user/tab-user-auth.twig @@ -20,11 +20,11 @@ {{ lang.user.open_webmail_sso }} {% elseif dual_login %} - + {{ lang.user.open_webmail_sso }} {% else %} - + {{ lang.user.open_webmail_sso }} {% endif %} diff --git a/data/web/templates/index.twig b/data/web/templates/user_index.twig similarity index 100% rename from data/web/templates/index.twig rename to data/web/templates/user_index.twig diff --git a/data/web/user.php b/data/web/user.php index 19aafdddc..7c34ba953 100644 --- a/data/web/user.php +++ b/data/web/user.php @@ -1,29 +1,8 @@ "get_friendly_names")); - $username = $_SESSION['mailcow_cc_username']; - - $template = 'domainadmin.twig'; - $template_data = [ - 'acl' => $_SESSION['acl'], - 'acl_json' => json_encode($_SESSION['acl']), - 'user_spam_score' => mailbox('get', 'spam_score', $username), - 'tfa_data' => $tfa_data, - 'fido2_data' => $fido2_data, - 'lang_user' => json_encode($lang['user']), - 'lang_datatables' => json_encode($lang['datatables']), - ]; -} -elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') { +if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') { /* / USER @@ -95,6 +74,14 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == ' 'lang_datatables' => json_encode($lang['datatables']), ]; } +elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'admin') { + header('Location: /admin/dashboard'); + exit(); +} +elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'domainadmin') { + header('Location: /domainadmin/mailbox'); + exit(); +} else { header('Location: /'); exit();
Hostname