# io.Connect Desktop 10.0.4

Source: https://docs.interop.io/desktop/getting-started/changelog/10-0-4/index.html

## io.Connect Desktop 10.0.4

*Release date: 06.03.2026*

| Components | Version |
|------------|---------|
| Electron | [39.6.0](https://releases.electronjs.org/release/v39.6.0) |
| Chromium | 142.0.7444.265 |
| Node.js | 22.22.0 |

The following libraries are bundled with **io.Connect Desktop** 10.0.4 and will be used for [auto injection](https://docs.interop.io/desktop/getting-started/how-to/interop-enable-your-apps/javascript/index.md#auto_injection):

| Injected Library | Version |
|------------------|---------|
| [`@interopio/desktop`](https://www.npmjs.com/package/@interopio/desktop) | [6.18](https://docs.interop.io/desktop/getting-started/how-to/interop-enable-your-apps/javascript/index.md#changelog-interopiodesktop-6180) |
| [`@interopio/fdc3`](https://www.npmjs.com/package/@interopio/fdc3) | 2.7 |

## New Features

> ### SSO with Microsoft Entra ID
>
> **io.Connect Desktop** now supports seamless [SSO authentication with Microsoft Entra ID](https://docs.interop.io/desktop/getting-started/security/index.md#authentication-microsoft_entra_id_sso) 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](https://docs.interop.io/desktop/developers/configuration/system/index.md) file:
>
> ```json
> {
>     "entraSSO": {
>         "enabled": true,
>         "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](https://docs.interop.io/desktop/developers/seed-project/index.md#building_for_production-install_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:
>
> ```cmd
> # 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:
>
> ```json
> // 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:
>
> ```json
> // 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()`](https://docs.interop.io/desktop/reference/javascript/apps/inmemorystore/index.md#InMemoryStore-remove) method of the `InMemoryStore` object now supports [removing multiple app definitions](https://docs.interop.io/desktop/capabilities/app-management/javascript/index.md#inmemory_store-remove) at a time by passing an array of app names:
>
> ```javascript
> const appsToRemove = { name: ["my-app", "my-other-app"] };
>
> await io.apps.registry.inMemory.remove(appsToRemove);
> ```

> ### Custom Configuration for Intent Handlers
>
> [Intent handlers](https://docs.interop.io/desktop/capabilities/data-sharing/intents/overview/index.md#defining_intents) can now receive custom configuration via the `"customConfig"` property of the object for defining an Intent in the `"intents"` array in the [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md):
>
> ```json
> {
>     "intents": [
>         {
>             "name": "ViewChart",
>             "displayName": "Instrument Chart",
>             "contexts": ["Instrument"],
>             "customConfig": {
>                 "chartType": "candlestick",
>                 "theme": "dark"
>             }
>         }
>     ]
> }
> ```
>
> Custom Intent handler configuration can also be passed [dynamically](https://docs.interop.io/desktop/capabilities/data-sharing/intents/javascript/index.md#custom_configuration_for_intent_handlers) via the [`AddIntentListenerRequest`](https://docs.interop.io/desktop/reference/javascript/intents/addintentlistenerrequest/index.md) object when using the [`register()`](https://docs.interop.io/desktop/reference/javascript/intents/api/index.md#API-register) method.
>
> To pass custom configuration for the Intent handler, use the `customConfig` property of the `AddIntentListenerRequest` object when registering an Intent:
>
> ```javascript
> // 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`](https://docs.interop.io/desktop/reference/javascript/intents/intenthandler/index.md) object when [finding Intents](https://docs.interop.io/desktop/capabilities/data-sharing/intents/javascript/index.md#finding_intents) or when [filtering Intent handlers](https://docs.interop.io/desktop/capabilities/data-sharing/intents/javascript/index.md#filtering_intent_handlers):
>
> ```javascript
> // 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.
