public
nobgit
read
NobMail
Based on mailcow: dockerized
Languages
Repository composition by tracked source files.
PHP
49%
JavaScript
35%
HTML
9%
CSS
4%
Shell
2%
Python
1%
Lua
0%
Perl
0%
Ruby
0%
SCSS
0%
Create file
Wiki Documentation
Clone
https://nobgit.com/orgs/nobgit/nobmail.git
ssh://[email protected]:2222/orgs/nobgit/nobmail.git
Commit
[Web] Separate Login pages
aca01c8a
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 ++--
data/web/templates/{debug.twig => dashboard.twig} | 4 +-
data/web/templates/domainadmin_index.twig | 91 +++++++
data/web/templates/user/tab-user-auth.twig | 4 +-
data/web/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
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 4a099cb6..894b1c64 100644
--- a/data/web/debug.php
+++ b/data/web/admin/dashboard.php
@@ -1,8 +1,17 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.admin.inc.php';
-if (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != "admin") {
- header('Location: /');
+if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'domainadmin') {
+ header('Location: /domainadmin/mailbox');
+ exit();
+}
+elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') {
+ header('Location: /user');
+ exit();
+}
+elseif (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != "admin") {
+ header('Location: /admin');
exit();
}
@@ -16,7 +25,7 @@ if (!isset($_SESSION['gal']) && $license_cache = $redis->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 00000000..05ba7033
--- /dev/null
+++ b/data/web/admin/index.php
@@ -0,0 +1,29 @@
+<?php
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.admin.inc.php';
+
+if (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();
+}
+elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') {
+ header('Location: /user');
+ exit();
+}
+
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php';
+$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
+$_SESSION['index_query_string'] = $_SERVER['QUERY_STRING'];
+
+
+$template = 'admin_index.twig';
+$template_data = [
+ 'login_delay' => @$_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 a84e32c4..d0073bbd 100644
--- a/data/web/mailbox.php
+++ b/data/web/admin/mailbox.php
@@ -1,10 +1,20 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.admin.inc.php';
-if (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
- header('Location: /');
+if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'domainadmin') {
+ header('Location: /domainadmin/mailbox');
exit();
}
+elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') {
+ header('Location: /user');
+ exit();
+}
+elseif (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != "admin") {
+ header('Location: /admin');
+ exit();
+}
+
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php';
$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
@@ -14,7 +24,7 @@ $js_minifier->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 ffce8d8b..85ec5940 100644
--- a/data/web/queue.php
+++ b/data/web/admin/queue.php
@@ -1,8 +1,17 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.admin.inc.php';
-if (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != "admin") {
- header('Location: /');
+if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'domainadmin') {
+ header('Location: /domainadmin/mailbox');
+ exit();
+}
+elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') {
+ header('Location: /user');
+ exit();
+}
+elseif (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != "admin") {
+ header('Location: /admin');
exit();
}
@@ -11,7 +20,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php';
$js_minifier->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 5a8895de..c21d43f0 100644
--- a/data/web/admin.php
+++ b/data/web/admin/system.php
@@ -1,8 +1,17 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.admin.inc.php';
-if (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != "admin") {
- header('Location: /');
+if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'domainadmin') {
+ header('Location: /domainadmin/mailbox');
+ exit();
+}
+elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') {
+ header('Location: /user');
+ exit();
+}
+elseif (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != "admin") {
+ header('Location: /admin');
exit();
}
diff --git a/data/web/css/site/admin.css b/data/web/css/site/admin.css
index e49046b0..b5414802 100644
--- a/data/web/css/site/admin.css
+++ b/data/web/css/site/admin.css
@@ -59,9 +59,6 @@ body.modal-open {
.table-condensed > 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 00000000..2d909f97
--- /dev/null
+++ b/data/web/domainadmin/index.php
@@ -0,0 +1,28 @@
+<?php
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.domainadmin.inc.php';
+
+if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'domainadmin') {
+ header('Location: /domainadmin/mailbox');
+ exit();
+}
+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();
+}
+
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php';
+$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
+$_SESSION['index_query_string'] = $_SERVER['QUERY_STRING'];
+
+$template = 'domainadmin_index.twig';
+$template_data = [
+ 'login_delay' => @$_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 00000000..bb2ef16f
--- /dev/null
+++ b/data/web/domainadmin/mailbox.php
@@ -0,0 +1,58 @@
+<?php
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.domainadmin.inc.php';
+
+if (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();
+}
+elseif (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != "domainadmin") {
+ header('Location: /domainadmin');
+ exit();
+}
+
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php';
+$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
+
+
+
+$js_minifier->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 00000000..7f1b392e
--- /dev/null
+++ b/data/web/domainadmin/user.php
@@ -0,0 +1,44 @@
+<?php
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.domainadmin.inc.php';
+
+if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'domainadmin') {
+
+ /*
+ / DOMAIN ADMIN
+ */
+
+ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php';
+ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
+ $tfa_data = get_tfa();
+ $fido2_data = fido2(array("action" => "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 ed41379f..23362427 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 7fb619d4..156856c2 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 5738e7c0..deb5da8f 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 67bdd35b..bbc08cf1 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 00000000..5b1061f7
--- /dev/null
+++ b/data/web/inc/triggers.admin.inc.php
@@ -0,0 +1,93 @@
+<?php
+
+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: /admin/dashboard");
+ 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: /admin");
+}
+
+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" => "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 00000000..9ee53d67
--- /dev/null
+++ b/data/web/inc/triggers.domainadmin.inc.php
@@ -0,0 +1,62 @@
+<?php
+// SSO Domain Admin
+if (!empty($_GET['sso_token'])) {
+ $username = domain_admin_sso('check', $_GET['sso_token']);
+
+ if ($username !== false) {
+ session_regenerate_id(true);
+ $_SESSION['mailcow_cc_username'] = $username;
+ $_SESSION['mailcow_cc_role'] = 'domainadmin';
+ header('Location: /domainadmin/mailbox');
+ }
+}
+
+if (isset($_POST["verify_tfa_login"])) {
+ if (verify_tfa_login($_SESSION['pending_mailcow_cc_username'], $_POST)) {
+ if ($_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: /domainadmin/mailbox");
+ 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: /domainadmin");
+}
+
+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" => "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 00000000..dd88fad5
--- /dev/null
+++ b/data/web/inc/triggers.global.inc.php
@@ -0,0 +1,48 @@
+<?php
+if (isset($_POST["quick_release"])) {
+ quarantine('quick_release', $_POST["quick_release"]);
+}
+
+if (isset($_POST["quick_delete"])) {
+ quarantine('quick_delete', $_POST["quick_delete"]);
+}
+
+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));
+ }
+}
+?>
diff --git a/data/web/inc/triggers.inc.php b/data/web/inc/triggers.inc.php
deleted file mode 100644
index b0c2237d..00000000
--- a/data/web/inc/triggers.inc.php
+++ /dev/null
@@ -1,263 +0,0 @@
-<?php
-// handle iam authentication
-if ($iam_provider){
- if (isset($_GET['iam_sso'])){
- // redirect for sso
- $redirect_uri = identity_provider('get-redirect');
- $redirect_uri = !empty($redirect_uri) ? $redirect_uri : '/';
- header('Location: ' . $redirect_uri);
- die();
- }
- if ($_SESSION['iam_token'] && $_SESSION['iam_refresh_token']) {
- // Session found, try to refresh
- $isRefreshed = identity_provider('refresh-token');
-
- if (!$isRefreshed){
- // Session could not be refreshed, redirect to provider
- $redirect_uri = identity_provider('get-redirect');
- $redirect_uri = !empty($redirect_uri) ? $redirect_uri : '/';
- header('Location: ' . $redirect_uri);
- die();
- }
- } elseif ($_GET['code'] && $_GET['state'] === $_SESSION['oauth2state']) {
- // Check given state against previously stored one to mitigate CSRF attack
- // Recieved access token in $_GET['code']
- // extract info and verify user
- identity_provider('verify-sso');
- }
-}
-
-// SSO Domain Admin
-if (!empty($_GET['sso_token'])) {
- $username = domain_admin_sso('check', $_GET['sso_token']);
-
- if ($username !== false) {
- $_SESSION['mailcow_cc_username'] = $username;
- $_SESSION['mailcow_cc_role'] = 'domainadmin';
- header('Location: /mailbox');
- }
-}
-
-if (isset($_POST["pw_reset_request"]) && !empty($_POST['username'])) {
- reset_password("issue", $_POST['username']);
- header("Location: /");
- exit;
-}
-if (isset($_POST["pw_reset"])) {
- $username = reset_password("check", $_POST['token']);
- $reset_result = reset_password("reset", array(
- 'new_password' => $_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 00000000..c16edc10
--- /dev/null
+++ b/data/web/inc/triggers.user.inc.php
@@ -0,0 +1,132 @@
+<?php
+// handle iam authentication
+if ($iam_provider){
+ if (isset($_GET['iam_sso'])){
+ // redirect for sso
+ $redirect_uri = identity_provider('get-redirect');
+ $redirect_uri = !empty($redirect_uri) ? $redirect_uri : '/';
+ header('Location: ' . $redirect_uri);
+ die();
+ }
+ if ($_SESSION['iam_token'] && $_SESSION['iam_refresh_token']) {
+ // Session found, try to refresh
+ $isRefreshed = identity_provider('refresh-token');
+
+ if (!$isRefreshed){
+ // Session could not be refreshed, redirect to provider
+ $redirect_uri = identity_provider('get-redirect');
+ $redirect_uri = !empty($redirect_uri) ? $redirect_uri : '/';
+ header('Location: ' . $redirect_uri);
+ die();
+ }
+ } elseif ($_GET['code'] && $_GET['state'] === $_SESSION['oauth2state']) {
+ // Check given state against previously stored one to mitigate CSRF attack
+ // Recieved access token in $_GET['code']
+ // extract info and verify user
+ identity_provider('verify-sso');
+ }
+}
+
+if (isset($_POST["pw_reset_request"]) && !empty($_POST['username'])) {
+ reset_password("issue", $_POST['username']);
+ header("Location: /");
+ exit;
+}
+if (isset($_POST["pw_reset"])) {
+ $username = reset_password("check", $_POST['token']);
+ $reset_result = reset_password("reset", array(
+ 'new_password' => $_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 0282e483..1e91cb78 100644
--- a/data/web/index.php
+++ b/data/web/index.php
@@ -1,5 +1,6 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.user.inc.php';
if (isset($_SESSION['mailcow_cc_role']) && isset($_SESSION['oauth2_request'])) {
$oauth2_request = $_SESSION['oauth2_request'];
@@ -7,14 +8,6 @@ if (isset($_SESSION['mailcow_cc_role']) && isset($_SESSION['oauth2_request'])) {
header('Location: ' . $oauth2_request);
exit();
}
-elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'admin') {
- header('Location: /debug');
- exit();
-}
-elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'domainadmin') {
- header('Location: /mailbox');
- exit();
-}
elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') {
$user_details = mailbox("get", "mailbox_details", $_SESSION['mailcow_cc_username']);
$is_dual = (!empty($_SESSION["dual-login"]["username"])) ? true : false;
@@ -25,6 +18,14 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
}
exit();
}
+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();
+}
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php';
$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
@@ -36,7 +37,7 @@ if ($iam_provider){
}
-$template = 'index.twig';
+$template = 'user_index.twig';
$template_data = [
'oauth2_request' => @$_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 0c9ffb3d..3c21c18b 100644
--- a/data/web/js/site/mailbox.js
+++ b/data/web/js/site/mailbox.js
@@ -939,7 +939,7 @@ jQuery(function($){
'<a href="#" data-action="delete_selected" data-id="single-mailbox" data-api-url="delete/mailbox" data-item="' + encodeURIComponent(item.username) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'<a href="/index.php?duallogin=' + encodeURIComponent(item.username) + '" class="login_as btn btn-sm btn-xs-lg btn-xs-half btn-success"><i class="bi bi-person-fill"></i> Login</a>';
if (ALLOW_ADMIN_EMAIL_LOGIN) {
- item.action += '<a href="/sogo-auth.php?login=' + encodeURIComponent(item.username) + '" class="login_as btn btn-sm btn-xs-lg btn-xs-half btn-primary" target="_blank"><i class="bi bi-envelope-fill"></i> SOGo</a>';
+ item.action += '<a href="/sogo-auth.php?login=' + encodeURIComponent(item.username) + '" class="login_as btn btn-sm btn-xs-lg btn-xs-half btn-primary"><i class="bi bi-envelope-fill"></i> SOGo</a>';
}
item.action += '</div>';
}
diff --git a/data/web/reset-password.php b/data/web/reset-password.php
index a0225dc6..7544d40c 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 00000000..4127a6a2
--- /dev/null
+++ b/data/web/templates/admin_index.twig
@@ -0,0 +1,91 @@
+{% extends 'base.twig' %}
+
+{% block navbar %}{% endblock %}
+
+{% block content %}
+<div class="row mb-4" style="margin-top: 60px">
+ <div class="col-12 col-md-7 col-lg-6 col-xl-5 ms-auto me-auto">
+ <div class="card">
+ <div class="card-header d-flex align-items-center">
+ <i class="bi bi-person-fill me-2"></i> {{ lang.login.login }}
+ <div class="ms-auto form-check form-switch my-auto d-flex align-items-center">
+ <label class="form-check-label"><i class="bi bi-moon-fill"></i></label>
+ <input class="form-check-input ms-2" type="checkbox" id="dark-mode-toggle">
+ </div>
+ </div>
+ <div class="card-body">
+ <div class="text-center mailcow-logo mb-4">
+ <img class="main-logo" src="{{ logo|default('/img/cow_mailcow.svg') }}" alt="mailcow">
+ <img class="main-logo-dark" src="{{ logo_dark|default('/img/cow_mailcow.svg') }}" alt="mailcow-logo-dark">
+ </div>
+ {% if ui_texts.ui_announcement_text and ui_texts.ui_announcement_active %}
+ <div class="my-4 alert alert-{{ ui_texts.ui_announcement_type }} rot-enc ui-announcement-alert">{{ ui_texts.ui_announcement_text|rot13 }}</div>
+ {% endif %}
+ <form method="post" autofill="off">
+ <div class="d-flex mt-3">
+ <label class="visually-hidden" for="login_user">{{ lang.login.username }}</label>
+ <div class="input-group">
+ <div class="input-group-text"><i class="bi bi-person-fill"></i></div>
+ <input name="login_user" autocorrect="off" autocapitalize="none" type="text" id="login_user" class="form-control" placeholder="{{ lang.login.username }}" required="" autofocus="" autocomplete="username">
+ </div>
+ </div>
+ <div class="d-flex mt-3">
+ <label class="visually-hidden" for="pass_user">{{ lang.login.password }}</label>
+ <div class="input-group">
+ <div class="input-group-text"><i class="bi bi-lock-fill"></i></div>
+ <input name="pass_user" type="password" id="pass_user" class="form-control" placeholder="{{ lang.login.password }}" required="" autocomplete="current-password">
+ </div>
+ </div>
+ <div class="d-flex justify-content-between mt-4" style="position: relative">
+ <button type="submit" class="btn btn-xs-lg btn-success" value="Login">{{ lang.login.login }}</button> <div class="d-grid d-sm-block">
+ <button type="button" {% if available_languages|length == 1 %}disabled="true"{% endif %} class="btn btn-secondary ms-auto dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ <span class="flag-icon flag-icon-{{ mailcow_locale[-2:] }}"></span>
+ </button>
+ <ul class="dropdown-menu ms-auto login">
+ {% for key, val in available_languages %}
+ <li>
+ <a class="dropdown-item {% if mailcow_locale == key %}active{% endif %}" href="?{{ query_string({'lang': key}) }}">
+ <span class="flag-icon flag-icon-{{ key[-2:] }}"></span>{{ val }}
+ </a>
+ </li>
+ {% endfor %}
+ </ul>
+ </div>
+ </div>
+ </form>
+ <div class="hr-title mt-5"><strong>{{ lang.login.other_logins }}</strong></div>
+ <div class="d-flex flex-column align-items-center">
+ <a class="btn btn-xs-lg btn-secondary w-100" style="max-width: 400px;" href="#" id="fido2-login"><i class="bi bi-shield-fill-check"></i> {{ lang.login.fido2_webauthn }}</a>
+ </div>
+ {% if login_delay %}
+ <p><div class="my-4 alert alert-info">{{ lang.login.delayed|format(login_delay) }}</b></div></p>
+ {% endif %}
+ <div class="my-4" id="fido2-alerts"></div>
+ {% if (mailcow_apps or app_links) and not hide_mailcow_apps %}
+ <legend><i class="bi bi-link-45deg"></i> {{ ui_texts.apps_name|raw }}</legend><hr />
+ <div class="my-2 d-grid gap-2 d-sm-block apps">
+ {% for app in mailcow_apps %}
+ {% if not app.hide %}
+ {% if not skip_sogo or not is_uri('SOGo', app.link) %}
+ <div class="m-2">
+ <a href="{{ app.link }}" role="button" {% if app.description %}title="{{ app.description }}"{% endif %} class="btn btn-primary btn-block">{{ app.name }}</a>
+ </div>
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ {% for row in app_links %}
+ {% for key, val in row %}
+ {% if not val.hide %}
+ <div class="m-2">
+ <a href="{{ val.link }}" role="button" class="btn btn-primary btn-block">{{ key }}</a>
+ </div>
+ {% endif %}
+ {% endfor %}
+ {% endfor %}
+ </div>
+ {% endif %}
+ </div>
+ </div>
+ </div>
+</div>
+{% endblock %}
diff --git a/data/web/templates/base.twig b/data/web/templates/base.twig
index 2634574d..4d0a3025 100644
--- a/data/web/templates/base.twig
+++ b/data/web/templates/base.twig
@@ -66,27 +66,36 @@
<li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false">{{ lang.header.mailcow_system }}</a>
<ul class="dropdown-menu">
- <li><a href="/debug" class="dropdown-item {% if is_uri('debug') %}active{% endif %}">{{ lang.header.debug }}</a></li>
- <li><a href="/admin" class="dropdown-item {% if is_uri('admin') %}active{% endif %}">{{ lang.header.mailcow_config }}</a></li>
+ <li><a href="/admin/dashboard" class="dropdown-item {% if is_uri('dashboard') %}active{% endif %}">{{ lang.header.debug }}</a></li>
+ <li><a href="/admin/system" class="dropdown-item {% if is_uri('system') %}active{% endif %}">{{ lang.header.mailcow_config }}</a></li>
+ </ul>
+ </li>
+ <li class="nav-item dropdown">
+ <a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false">{{ lang.header.email }}</a>
+ <ul class="dropdown-menu">
+ <li><a href="/admin/mailbox" class="dropdown-item {% if is_uri('mailbox') %}active{% endif %}">{{ lang.header.mailcow_config }}</a></li>
+ <li><a href="/quarantine" class="dropdown-item {% if is_uri('quarantine') %}active{% endif %}">{{ lang.header.quarantine }}</a></li>
+ <li><a href="/admin/queue" class="dropdown-item {% if is_uri('queue') %}active{% endif %}">{{ lang.queue.queue_manager }}</a></li>
+ <li><a href="#" class="dropdown-item" data-bs-toggle="modal" data-container="sogo-mailcow" data-bs-target="#RestartContainer">{{ lang.header.restart_sogo }}</a></li>
</ul>
</li>
{% endif %}
- {% if mailcow_cc_role != 'admin' %}
+ {% if mailcow_cc_role == 'domainadmin' %}
+ <li class="nav-item dropdown">
+ <a href="/domainadmin/user" class="nav-link" role="button" aria-expanded="false">{{ lang.header.user_settings }}</a>
+ </li>
+ {% elseif mailcow_cc_role == 'user' %}
<li class="nav-item dropdown">
<a href="/user" class="nav-link" role="button" aria-expanded="false">{{ lang.header.user_settings }}</a>
</li>
{% endif %}
- {% if mailcow_cc_role == 'admin' or mailcow_cc_role == 'domainadmin' %}
+ {% if mailcow_cc_role == 'domainadmin' %}
<li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false">{{ lang.header.email }}</a>
<ul class="dropdown-menu">
- <li><a href="/mailbox" class="dropdown-item {% if is_uri('mailbox') %}active{% endif %}">{{ lang.header.mailcow_config }}</a></li>
+ <li><a href="/domainadmin/mailbox" class="dropdown-item {% if is_uri('mailbox') %}active{% endif %}">{{ lang.header.mailcow_config }}</a></li>
<li><a href="/quarantine" class="dropdown-item {% if is_uri('quarantine') %}active{% endif %}">{{ lang.header.quarantine }}</a></li>
- {% if mailcow_cc_role == 'admin' %}
- <li><a href="/queue" class="dropdown-item {% if is_uri('queue') %}active{% endif %}">{{ lang.queue.queue_manager }}</a></li>
- <li><a href="#" class="dropdown-item" data-bs-toggle="modal" data-container="sogo-mailcow" data-bs-target="#RestartContainer">{{ lang.header.restart_sogo }}</a></li>
- {% endif %}
</ul>
</li>
{% 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: <a href="{{ mailcow_info.git_project_url }}/releases/tag/{{ mailcow_info.version_tag }}" target="_blank">{{ mailcow_info.version_tag }}
</a>
</span>
- {% endif %}
+ {% endif %}
{% if mailcow_cc_username and mailcow_info.mailcow_branch|lower == "nightly" and mailcow_info.version_tag|default %}
<span class="version">
🛠️🐮 + 🐋 = 💕
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 c148856c..8f8c2d99 100644
--- a/data/web/templates/debug.twig
+++ b/data/web/templates/dashboard.twig
@@ -42,8 +42,8 @@
<img class="main-logo-dark img-responsive my-auto m-auto" alt="mailcow-logo-dark" style="max-width: 85%; max-height: 85%;" src="{{ logo_dark|default('/img/cow_mailcow.svg') }}">
</div>
<div class="col-sm-12 col-md-8">
- <div class="table-responsive" style="margin-top: 10px;">
- <table class="table table-striped table-condensed w-100">
+ <div style="margin-top: 10px;">
+ <table class="table table-striped w-100">
<tbody>
<tr>
<td>Hostname</td>
diff --git a/data/web/templates/domainadmin_index.twig b/data/web/templates/domainadmin_index.twig
new file mode 100644
index 00000000..4127a6a2
--- /dev/null
+++ b/data/web/templates/domainadmin_index.twig
@@ -0,0 +1,91 @@
+{% extends 'base.twig' %}
+
+{% block navbar %}{% endblock %}
+
+{% block content %}
+<div class="row mb-4" style="margin-top: 60px">
+ <div class="col-12 col-md-7 col-lg-6 col-xl-5 ms-auto me-auto">
+ <div class="card">
+ <div class="card-header d-flex align-items-center">
+ <i class="bi bi-person-fill me-2"></i> {{ lang.login.login }}
+ <div class="ms-auto form-check form-switch my-auto d-flex align-items-center">
+ <label class="form-check-label"><i class="bi bi-moon-fill"></i></label>
+ <input class="form-check-input ms-2" type="checkbox" id="dark-mode-toggle">
+ </div>
+ </div>
+ <div class="card-body">
+ <div class="text-center mailcow-logo mb-4">
+ <img class="main-logo" src="{{ logo|default('/img/cow_mailcow.svg') }}" alt="mailcow">
+ <img class="main-logo-dark" src="{{ logo_dark|default('/img/cow_mailcow.svg') }}" alt="mailcow-logo-dark">
+ </div>
+ {% if ui_texts.ui_announcement_text and ui_texts.ui_announcement_active %}
+ <div class="my-4 alert alert-{{ ui_texts.ui_announcement_type }} rot-enc ui-announcement-alert">{{ ui_texts.ui_announcement_text|rot13 }}</div>
+ {% endif %}
+ <form method="post" autofill="off">
+ <div class="d-flex mt-3">
+ <label class="visually-hidden" for="login_user">{{ lang.login.username }}</label>
+ <div class="input-group">
+ <div class="input-group-text"><i class="bi bi-person-fill"></i></div>
+ <input name="login_user" autocorrect="off" autocapitalize="none" type="text" id="login_user" class="form-control" placeholder="{{ lang.login.username }}" required="" autofocus="" autocomplete="username">
+ </div>
+ </div>
+ <div class="d-flex mt-3">
+ <label class="visually-hidden" for="pass_user">{{ lang.login.password }}</label>
+ <div class="input-group">
+ <div class="input-group-text"><i class="bi bi-lock-fill"></i></div>
+ <input name="pass_user" type="password" id="pass_user" class="form-control" placeholder="{{ lang.login.password }}" required="" autocomplete="current-password">
+ </div>
+ </div>
+ <div class="d-flex justify-content-between mt-4" style="position: relative">
+ <button type="submit" class="btn btn-xs-lg btn-success" value="Login">{{ lang.login.login }}</button> <div class="d-grid d-sm-block">
+ <button type="button" {% if available_languages|length == 1 %}disabled="true"{% endif %} class="btn btn-secondary ms-auto dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ <span class="flag-icon flag-icon-{{ mailcow_locale[-2:] }}"></span>
+ </button>
+ <ul class="dropdown-menu ms-auto login">
+ {% for key, val in available_languages %}
+ <li>
+ <a class="dropdown-item {% if mailcow_locale == key %}active{% endif %}" href="?{{ query_string({'lang': key}) }}">
+ <span class="flag-icon flag-icon-{{ key[-2:] }}"></span>{{ val }}
+ </a>
+ </li>
+ {% endfor %}
+ </ul>
+ </div>
+ </div>
+ </form>
+ <div class="hr-title mt-5"><strong>{{ lang.login.other_logins }}</strong></div>
+ <div class="d-flex flex-column align-items-center">
+ <a class="btn btn-xs-lg btn-secondary w-100" style="max-width: 400px;" href="#" id="fido2-login"><i class="bi bi-shield-fill-check"></i> {{ lang.login.fido2_webauthn }}</a>
+ </div>
+ {% if login_delay %}
+ <p><div class="my-4 alert alert-info">{{ lang.login.delayed|format(login_delay) }}</b></div></p>
+ {% endif %}
+ <div class="my-4" id="fido2-alerts"></div>
+ {% if (mailcow_apps or app_links) and not hide_mailcow_apps %}
+ <legend><i class="bi bi-link-45deg"></i> {{ ui_texts.apps_name|raw }}</legend><hr />
+ <div class="my-2 d-grid gap-2 d-sm-block apps">
+ {% for app in mailcow_apps %}
+ {% if not app.hide %}
+ {% if not skip_sogo or not is_uri('SOGo', app.link) %}
+ <div class="m-2">
+ <a href="{{ app.link }}" role="button" {% if app.description %}title="{{ app.description }}"{% endif %} class="btn btn-primary btn-block">{{ app.name }}</a>
+ </div>
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ {% for row in app_links %}
+ {% for key, val in row %}
+ {% if not val.hide %}
+ <div class="m-2">
+ <a href="{{ val.link }}" role="button" class="btn btn-primary btn-block">{{ key }}</a>
+ </div>
+ {% endif %}
+ {% endfor %}
+ {% endfor %}
+ </div>
+ {% endif %}
+ </div>
+ </div>
+ </div>
+</div>
+{% endblock %}
diff --git a/data/web/templates/user/tab-user-auth.twig b/data/web/templates/user/tab-user-auth.twig
index 5c90bedf..a7e02543 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 }} <i class="bi bi-arrow-right"></i>
</button>
{% elseif dual_login %}
- <a target="_blank" href="/sogo-auth.php?login={{ mailcow_cc_username }}" role="button" class="btn btn-primary btn-lg btn-block btn-xs-lg w-100">
+ <a href="/sogo-auth.php?login={{ mailcow_cc_username }}" role="button" class="btn btn-primary btn-lg btn-block btn-xs-lg w-100">
{{ lang.user.open_webmail_sso }} <i class="bi bi-arrow-right"></i>
</a>
{% else %}
- <a target="_blank" href="/SOGo/so" role="button" class="btn btn-primary btn-lg btn-block btn-xs-lg w-100">
+ <a href="/SOGo/so" role="button" class="btn btn-primary btn-lg btn-block btn-xs-lg w-100">
{{ lang.user.open_webmail_sso }} <i class="bi bi-arrow-right"></i>
</a>
{% 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 19aafddd..7c34ba95 100644
--- a/data/web/user.php
+++ b/data/web/user.php
@@ -1,29 +1,8 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
-if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'domainadmin') {
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.user.inc.php';
- /*
- / DOMAIN ADMIN
- */
-
- require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php';
- $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
- $tfa_data = get_tfa();
- $fido2_data = fido2(array("action" => "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();