Changelog

io.Connect Desktop 10.0.4

Release date: 06.03.2026

Components Version
Electron 39.6.0
Chromium 142.0.7444.265
Node.js 22.22.0

New Features

SSO with Microsoft Entra ID

io.Connect Desktop now supports seamless SSO authentication with Microsoft Entra ID by automatically injecting Windows proof-of-possession cookies into requests to specified Microsoft Entra ID login URLs.

To enable SSO with Microsoft Entra ID, use the "entraSSO" top-level key in the system.json system configuration file:

{
    "entraSSO": {
        "urls": [
            "https://login.microsoftonline.com/*",
            "https://login.microsoft.com/*",
            "https://login.live.com/*",
            "https://*.microsoftonline.com/*"
        ]
    }
}

The "urls" property accepts a list of Microsoft Entra ID login URLs for which proof-of-possession cookies will be injected. Supports wildcard symbols (*). The default Microsoft Entra ID endpoints are included by default.

Seed Project Install & Uninstall Tasks

The io.Connect Desktop seed project now supports executing custom install and uninstall tasks via command-line triggers, enabling automated execution of scripts and commands during installation and uninstallation. Tasks are defined in OS-specific JSON configuration files within the modifications/build/iocd/install/ directory of the seed project - tasks.win32.json for Windows and tasks.darwin.json for macOS.

The following command line arguments trigger task execution:

Argument Platform Description
--post-install Cross-platform Execute install tasks (manual trigger).
--pre-uninstall Cross-platform Execute uninstall tasks (manual trigger).
--squirrel-install Windows Initial installation (triggered by Squirrel installer).
--squirrel-uninstall Windows Application uninstall (triggered by Squirrel installer).
--squirrel-updated Windows Application update (triggered by Squirrel installer).

The --post-install and --pre-uninstall flags can be used if you aren't using a Squirrel-based installer or if you want to manually test the install tasks:

# Windows
io-connect-desktop.exe --post-install

# macOS
open -a "io.Connect Desktop" --args --post-install

The following example demonstrates configuring install and uninstall tasks for Windows:

// tasks.win32.json
{
    "installTasks": [
        {
            "type": "run",
            "args": {
                "filename": "cmd.exe",
                "args": "/c copy-resources.bat",
                "hide": true
            }
        }
    ],
    "uninstallTasks": [
        {
            "type": "run",
            "args": {
                "filename": "cmd.exe",
                "args": "/c cleanup.bat",
                "hide": true
            }
        }
    ]
}

The following example demonstrates configuring install and uninstall tasks for macOS:

// tasks.darwin.json
{
    "installTasks": [
        {
            "type": "run",
            "args": {
                "filename": "/bin/bash",
                "args": "setup.sh --silent"
            }
        }
    ],
    "uninstallTasks": [
        {
            "type": "run",
            "args": {
                "filename": "/bin/bash",
                "args": "cleanup.sh"
            }
        }
    ]
}

Batch Removal of In-Memory App Definitions

The remove() method of the InMemoryStore object now supports removing multiple app definitions at a time by passing an array of app names:

const appsToRemove = { name: ["my-app", "my-other-app"] };

await io.apps.registry.inMemory.remove(appsToRemove);

Custom Configuration for Intent Handlers

Intent handlers can now receive custom configuration via the "customConfig" property of the object for defining an Intent in the "intents" array in the app definition:

{
    "intents": [
        {
            "name": "ViewChart",
            "displayName": "Instrument Chart",
            "contexts": ["Instrument"],
            "customConfig": {
                "chartType": "candlestick",
                "theme": "dark"
            }
        }
    ]
}

Custom Intent handler configuration can also be passed dynamically via the AddIntentListenerRequest object when using the register() method.

To pass custom configuration for the Intent handler, use the customConfig property of the AddIntentListenerRequest object when registering an Intent:

// Passing custom configuration when registering an Intent dynamically.
const intent = {
    intent: "ViewChart",
    contextTypes: ["Instrument"],
    // Custom configuration for the Intent handler.
    customConfig: {
        chartType: "candlestick"
    }
};

const contextHandler = (context) => {
    const contextType = context.type;

    if (contextType === "Instrument") {
        const data = context.data;
        // App-specific logic for handling the new context data.
    }
}

await io.intents.register(intent, contextHandler);

To access the custom configuration for an Intent handler, use the customConfig property of the IntentHandler object when finding Intents or when filtering Intent handlers:

// Accessing the custom configuration for an Intent handler when finding Intents.
const viewChartIntent = (await io.intents.find("ViewChart"))[0];

viewChartIntent.handlers.forEach(handler => {
    console.log(`Handler: ${handler.applicationName}, config: ${JSON.stringify(handler.customConfig)}`);
});

// Accessing the custom configuration for an Intent handler when filtering Intent handlers.
const { handlers } = await io.intents.filterHandlers({ intent: "ViewChart" });

handlers.forEach(handler => {
    console.log(`Handler: ${handler.applicationName}, config: ${JSON.stringify(handler.customConfig)}`);
});

Improvements & Bug Fixes

  • Upgraded to Electron 39.6.0 (Chromium 142).

  • Improved handling of internal file paths in the platform bundle to prevent issues with deployment build systems that may remove or filter directories based on naming conventions.

  • Improved platform handling of platform console output logging.

  • Improved compatibility when using newer versions of the @interopio/desktop library with older platform versions.

  • Fixed an issue where apps in Workspaces couldn't be closed while still loading when using lazy or delayed loading strategies.

  • Fixed an issue related to handling invalid properties in an app definition.

  • Fixed an issue related to rendering Workspace contents when the <WorkspaceContents /> component is wrapped in a custom container element.