diff --git a/data/web/json_api.php b/data/web/json_api.php index 3a6ad2659..b6e58c47d 100644 --- a/data/web/json_api.php +++ b/data/web/json_api.php @@ -1549,7 +1549,14 @@ if (isset($_GET['query'])) { if ($object == "sync-status") { process_get_return(\Mailcow\Identity\IdentityModule::fromGlobals()->api->getStatus()); } elseif($_SESSION['mailcow_cc_role'] === 'admin') { - process_get_return($iam_settings); + $iam_settings_out = $iam_settings; + // Read-only API keys never get the secrets of the identity provider + if (($_SESSION['mailcow_cc_api_access'] ?? '') == 'ro') { + foreach (array('client_secret', 'bindpass', 'access_token') as $iam_secret) { + if (isset($iam_settings_out[$iam_secret])) $iam_settings_out[$iam_secret] = '*'; + } + } + process_get_return($iam_settings_out); } else { process_get_return(null); } diff --git a/data/web/syncjob-oauth.php b/data/web/syncjob-oauth.php index 1046dc97a..44c60370c 100644 --- a/data/web/syncjob-oauth.php +++ b/data/web/syncjob-oauth.php @@ -35,7 +35,9 @@ if (empty($_SESSION['mailcow_cc_username']) || empty($_SESSION['mailcow_cc_role' } $context = \Mailcow\Core\Context::fromSession($_SESSION); $imapsync = \Mailcow\Imapsync\ImapsyncModule::fromGlobals($context); -if (!$context->hasAcl('syncjobs')) { +// Storing a token is a write: no read-only API keys, no session with pending 2FA setup or password update +if (!$context->hasAcl('syncjobs') || $context->isReadOnlyApi() + || !empty($_SESSION['pending_tfa_setup']) || !empty($_SESSION['pending_pw_update'])) { syncjob_oauth_finish(false, array('error' => 'access_denied')); }