Custom Logout Handler in Camunda Cockpit 7.14

With Camunda 7.14 the Cockpit itself and its plugin system has changed.

My goal is to write a custom logout handler - redirecting the logout to a given URL. Up to Camunda 7.13 this has been possible by writing an angular module similar to the following:

'use strict';
define('custom-logout', ['angular'], function (angular) {
    var customLogoutModule = angular.module('custom-logout', []).run(
        ['$rootScope', function ($rootScope) {

            $rootScope.$on('$viewContentLoaded', function (event) {
                // Get the HTML element of the header widget.
                var div = document.querySelector("[cam-widget-header]");

                // Get the only property on it, its key is jQuery<many numbers> and its value
                // contains the controller ($camWidgetHeaderController) and the isolated
                // Scope ($isolateScope). The logout function is defined in this scope.
                var jQueryKey = Object.getOwnPropertyNames(div)[0];
                var $isolateScope = div[jQueryKey]['$isolateScope'];
                $isolateScope.logout = function () {
                    // Do whatever you want to do on logout.
                    window.location.href = "logout"


Is there a way to achieve this in Camunda 7.14 as well? Maybe one of the Cockpit developers can give me a hint?

Thanks for your excellent work.

I mean, there is a quite dirty hack by intercepting all fetch requests and picking the api call to logout:

const doFetch = window.fetch;
window.fetch = function() {
	// Intercept calling logout
	if (arguments[0] === '/api/admin/auth/user/default/logout') {
	  // do whatever you want to do on logout
	  window.location.href = "logout"
	} else {
	  return doFetch.apply(this, arguments)

Intercepting all requests just due to the rarely used logout seems a bit strange. The question is, whether there is a clean solution?

Intercepting Fetch is one solution that will work. Another is to add an event listener to the logout button.

The only problem with this is to find the moment the button is rendered. Unfortunately, there is no exposed loading state or plugin point for the logout button. Instead, we have to manually check if the button is rendered yet :confused:

Here is my take on it:

// Wait until the element is present. We will use a Observer for it, but you can use other methods to observe it as well
let observer = new MutationObserver(() => {
  const logoutButton = document.querySelectorAll(
    ".Header > .UserInformation .DropdownOption > button"

  if (logoutButton) {
    logoutButton.addEventListener("click", () => {
      console.log("logout clicked");
      window.location.href = "logout";

observer.observe(document.body, {
  childList: true,
  subtree: true,
  attributes: false,
  characterData: false