mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2025-10-03 00:02:53 -04:00
Compare commits
2 Commits
28700cf9ff
...
3c24abc2e4
Author | SHA1 | Date | |
---|---|---|---|
|
3c24abc2e4 | ||
|
e42175ae6c |
@ -7,13 +7,19 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
});
|
||||
// logout function
|
||||
function mc_logout() {
|
||||
fetch("/", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
},
|
||||
body: "logout=1"
|
||||
}).then(() => window.location.href = '/');
|
||||
// Create and submit a logout form to trigger the logout process
|
||||
var form = document.createElement('form');
|
||||
form.method = 'POST';
|
||||
form.action = '/';
|
||||
|
||||
var logoutInput = document.createElement('input');
|
||||
logoutInput.type = 'hidden';
|
||||
logoutInput.name = 'logout';
|
||||
logoutInput.value = '1';
|
||||
|
||||
form.appendChild(logoutInput);
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
}
|
||||
|
||||
// Custom SOGo JS
|
||||
|
@ -2317,6 +2317,10 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
|
||||
if (!array_key_exists('login_provisioning', $settings)) {
|
||||
$settings['login_provisioning'] = 1;
|
||||
}
|
||||
// set end_session_url default if not exists
|
||||
if (!array_key_exists('end_session_url', $settings)) {
|
||||
$settings['end_session_url'] = '';
|
||||
}
|
||||
// return default client_scopes for generic-oidc if none is set
|
||||
if ($settings["authsource"] == "generic-oidc" && empty($settings["client_scopes"])){
|
||||
$settings["client_scopes"] = "openid profile email mailcow_template";
|
||||
@ -2391,6 +2395,7 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
|
||||
$_data['import_users'] = isset($_data['import_users']) ? intval($_data['import_users']) : 0;
|
||||
$_data['sync_interval'] = (!empty($_data['sync_interval'])) ? intval($_data['sync_interval']) : 15;
|
||||
$_data['sync_interval'] = $_data['sync_interval'] < 1 ? 1 : $_data['sync_interval'];
|
||||
$_data['end_session_url'] = (isset($_data['end_session_url']) && trim($_data['end_session_url']) !== '') ? trim($_data['end_session_url']) : null;
|
||||
$required_settings = array('authsource', 'server_url', 'realm', 'client_id', 'client_secret', 'redirect_url', 'version', 'mailpassword_flow', 'periodic_sync', 'import_users', 'sync_interval', 'ignore_ssl_error', 'login_provisioning');
|
||||
break;
|
||||
case "generic-oidc":
|
||||
@ -2398,6 +2403,7 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
|
||||
$_data['token_url'] = (!empty($_data['token_url'])) ? $_data['token_url'] : null;
|
||||
$_data['userinfo_url'] = (!empty($_data['userinfo_url'])) ? $_data['userinfo_url'] : null;
|
||||
$_data['client_scopes'] = (!empty($_data['client_scopes'])) ? $_data['client_scopes'] : "openid profile email mailcow_template";
|
||||
$_data['end_session_url'] = (isset($_data['end_session_url']) && trim($_data['end_session_url']) !== '') ? trim($_data['end_session_url']) : null;
|
||||
$required_settings = array('authsource', 'authorize_url', 'token_url', 'client_id', 'client_secret', 'redirect_url', 'userinfo_url', 'client_scopes', 'ignore_ssl_error', 'login_provisioning');
|
||||
break;
|
||||
case "ldap":
|
||||
@ -2456,6 +2462,12 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
// add end_session_url
|
||||
$_data['end_session_url'] = (isset($_data['end_session_url']) && trim($_data['end_session_url']) !== '') ? trim($_data['end_session_url']) : "";
|
||||
$stmt = $pdo->prepare("INSERT INTO identity_provider (`key`, `value`) VALUES ('end_session_url', :value) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`);");
|
||||
$stmt->bindParam(':value', $_data['end_session_url']);
|
||||
$stmt->execute();
|
||||
|
||||
// add mappers
|
||||
if (isset($_data['mappers']) && isset($_data['templates'])){
|
||||
$_data['mappers'] = (!is_array($_data['mappers'])) ? array($_data['mappers']) : $_data['mappers'];
|
||||
@ -2774,6 +2786,11 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
|
||||
set_user_loggedin_session($info['email']);
|
||||
$_SESSION['iam_token'] = $plain_token;
|
||||
$_SESSION['iam_refresh_token'] = $plain_refreshtoken;
|
||||
$_SESSION['iam_auth_source'] = $iam_settings['authsource'];
|
||||
// Store ID token if available for logout
|
||||
if (isset($token->getValues()['id_token'])) {
|
||||
$_SESSION['iam_id_token'] = $token->getValues()['id_token'];
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role']),
|
||||
@ -2850,6 +2867,11 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
|
||||
set_user_loggedin_session($info['email']);
|
||||
$_SESSION['iam_token'] = $plain_token;
|
||||
$_SESSION['iam_refresh_token'] = $plain_refreshtoken;
|
||||
$_SESSION['iam_auth_source'] = $iam_settings['authsource'];
|
||||
// Store ID token if available for logout
|
||||
if (isset($token->getValues()['id_token'])) {
|
||||
$_SESSION['iam_id_token'] = $token->getValues()['id_token'];
|
||||
}
|
||||
$_SESSION['return'][] = array(
|
||||
'type' => 'success',
|
||||
'log' => array(__FUNCTION__, $_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role']),
|
||||
@ -2963,6 +2985,37 @@ function identity_provider($_action = null, $_data = null, $_extra = null) {
|
||||
));
|
||||
return $res['access_token'];
|
||||
break;
|
||||
case "get-logout-url":
|
||||
// Generate logout URL for OIDC providers
|
||||
if ($iam_settings['authsource'] != 'keycloak' && $iam_settings['authsource'] != 'generic-oidc') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build the logout URL according to oidc spec
|
||||
// If end_session_url is empty, OIDC logout is disabled
|
||||
if (empty($iam_settings['end_session_url'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$post_logout_redirect_uri = (!empty($_data['post_logout_redirect_uri'])) ? $_data['post_logout_redirect_uri'] : null;
|
||||
|
||||
$params = [];
|
||||
if ($post_logout_redirect_uri) {
|
||||
$params['post_logout_redirect_uri'] = $post_logout_redirect_uri;
|
||||
}
|
||||
|
||||
// Add id_token_hint if available in session
|
||||
if (isset($_SESSION['iam_id_token'])) {
|
||||
$params['id_token_hint'] = $_SESSION['iam_id_token'];
|
||||
}
|
||||
|
||||
$logout_url = $iam_settings['end_session_url'];
|
||||
if (!empty($params)) {
|
||||
$logout_url .= '?' . http_build_query($params);
|
||||
}
|
||||
|
||||
return $logout_url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
function reset_password($action, $data = null) {
|
||||
|
@ -112,11 +112,43 @@ if (isset($_POST["logout"])) {
|
||||
}
|
||||
else {
|
||||
$role = $_SESSION["mailcow_cc_role"];
|
||||
|
||||
// Check if user was authenticated via OIDC and OIDC logout is enabled
|
||||
$oidc_logout_url = null;
|
||||
if (isset($_SESSION['iam_auth_source']) && ($_SESSION['iam_auth_source'] == 'keycloak' || $_SESSION['iam_auth_source'] == 'generic-oidc')) {
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.inc.php';
|
||||
|
||||
// Determine the schema
|
||||
$schema = 'http';
|
||||
if ((isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == "https") ||
|
||||
isset($_SERVER['HTTPS'])) {
|
||||
$schema = 'https';
|
||||
}
|
||||
|
||||
// Determine post-logout redirect URI based on role
|
||||
$post_logout_redirect_uri = $schema . '://' . $_SERVER['HTTP_HOST'];
|
||||
if ($role == "admin") {
|
||||
$post_logout_redirect_uri .= '/admin';
|
||||
} elseif ($role == "domainadmin") {
|
||||
$post_logout_redirect_uri .= '/domainadmin';
|
||||
} else {
|
||||
$post_logout_redirect_uri .= '/';
|
||||
}
|
||||
|
||||
$iam_provider = identity_provider('init');
|
||||
$iam_settings = identity_provider('get');
|
||||
$oidc_logout_url = identity_provider('get-logout-url', array('post_logout_redirect_uri' => $post_logout_redirect_uri));
|
||||
}
|
||||
|
||||
session_regenerate_id(true);
|
||||
session_unset();
|
||||
session_destroy();
|
||||
session_write_close();
|
||||
if ($role == "admin") {
|
||||
|
||||
// Redirect to OIDC logout URL if available, otherwise use standard logout
|
||||
if ($oidc_logout_url) {
|
||||
header("Location: " . $oidc_logout_url);
|
||||
} elseif($role == "admin") {
|
||||
header("Location: /admin");
|
||||
}
|
||||
elseif ($role == "domainadmin") {
|
||||
|
@ -243,6 +243,8 @@
|
||||
"iam_test_connection": "Verbindung Testen",
|
||||
"iam_token_url": "Token Endpunkt",
|
||||
"iam_userinfo_url": "User info Endpunkt",
|
||||
"iam_end_session_url": "End-Session-Endpunkt",
|
||||
"iam_end_session_url_info": "URL für RP-Initiated Logout nach OpenID Connect Spezifikation. Leer lassen, um OIDC-Logout zu deaktivieren.",
|
||||
"iam_username_field": "Username Feld",
|
||||
"iam_binddn": "Bind DN",
|
||||
"iam_use_ssl": "Benutze SSL",
|
||||
|
@ -250,6 +250,8 @@
|
||||
"iam_test_connection": "Test Connection",
|
||||
"iam_token_url": "Token endpoint",
|
||||
"iam_userinfo_url": "User info endpoint",
|
||||
"iam_end_session_url": "End session endpoint",
|
||||
"iam_end_session_url_info": "URL for RP-Initiated Logout according to OpenID Connect specification. Leave empty to disable OIDC logout.",
|
||||
"iam_username_field": "Username Field",
|
||||
"iam_binddn": "Bind DN",
|
||||
"iam_use_ssl": "Use SSL",
|
||||
|
@ -257,6 +257,19 @@
|
||||
<input class="form-control" type="number" min="1" name="sync_interval" style="width: 80px;" {% if iam_settings.sync_interval %}value="{{ iam_settings.sync_interval }}"{% else %}value="15"{% endif %}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="col-md-3 d-flex align-items-center justify-content-md-end">
|
||||
<label class="control-label" for="iam_keycloak_end_session_url">{{ lang.admin.iam_end_session_url }}:</label>
|
||||
</div>
|
||||
<div class="col-12 col-md-9 col-lg-4">
|
||||
<input type="text" class="form-control" id="iam_keycloak_end_session_url" name="end_session_url" value="{{ iam_settings.end_session_url }}" placeholder="https://keycloak.example.com/realms/mailcow/protocol/openid-connect/logout">
|
||||
<p class="text-muted">
|
||||
<small>
|
||||
{{ lang.admin.iam_end_session_url_info }}
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4 mb-2">
|
||||
<div class="offset-md-3 col-12 col-md-9 d-flex flex-wrap">
|
||||
<div class="btn-group mb-2">
|
||||
@ -460,6 +473,19 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-3 d-flex align-items-center justify-content-md-end">
|
||||
<label class="control-label" for="iam_generic_end_session_url">{{ lang.admin.iam_end_session_url }}:</label>
|
||||
</div>
|
||||
<div class="col-12 col-md-9 col-lg-4">
|
||||
<input type="text" class="form-control" id="iam_generic_end_session_url" name="end_session_url" value="{{ iam_settings.end_session_url }}" placeholder="https://auth.example.com/connect/endsession">
|
||||
<p class="text-muted">
|
||||
<small>
|
||||
{{ lang.admin.iam_end_session_url_info }}
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4 mb-2">
|
||||
<div class="offset-md-3 col-12 col-md-9 d-flex flex-wrap">
|
||||
<div class="btn-group mb-2">
|
||||
|
Loading…
x
Reference in New Issue
Block a user