Changelog
4.0
4.0.0
Release date: 28.08.2026
Breaking Changes
For more details, see the Upgrade section.
Dropped support for Node.js 20. io.Manager now requires Node.js 22 LTS or 24 LTS.
Dropped support for MongoDB 6. io.Manager now requires MongoDB 7 or later.
The io.Manager Server is now compatible with the io.Manager Admin UI only when their major and minor versions match. For example, io.Manager Server
4.0.xis compatible with io.Manager Admin UI4.0.x(any patch), but io.Manager Server4.0.0isn't compatible with io.Manager Admin UI4.1.0. Make sure to upgrade both packages together so that their major and minor versions stay aligned. Compatibility with@interopio/manager-api, io.Connect Desktop, and io.Connect Browser is unchanged.Removed the custom-store extension point. The
"custom"value for thetypeproperty of thestoretop-level key in the configuration object for initializing the io.Manager Server is no longer supported, along with the correspondingCustomStoreConfigconfiguration object. Thestoreproperty now only accepts aMongoStoreConfig, aPostgreSQLStoreConfig, or anMSSQLStoreConfigobject as a value. Existing deployments must switch to one of the three built-in database backends.Removed the
usersStoreproperty from theMongoStoreConfig,PostgreSQLStoreConfig, andMSSQLStoreConfigconfiguration objects. A separate users store can no longer be supplied alongside one of the built-in database backends.Removed the
StoreBase,UsersStoreBase, andBLOBStoreBaseabstract classes from the public API. Custom implementations of these classes can no longer be supplied to the io.Manager Server. The methods previously declared onUsersStoreBase(getUser,getAllUsers,addOrUpdateUser,removeUser,removeAllUsers, andsetUserOtherField) are now part of the built-in store implementations directly.The
GET /api/crashes/{id}/dumpendpoint of the io.Manager Server REST API now requires authentication and theIO_MANAGER:CRASHES:READpermission group. External callers that download crash dumps must be updated accordingly, or switched to the newCrashes.getDump(id): Promise<Blob>method on@interopio/manager-api, which reuses the client's existing authentication and returns the dump as aBlob.Changed the
GroupsServiceinterface used when providing a custom Groups service via thegroups_serviceconfiguration property. TheaddGroupmethod now takes aGroupobject and returns the created group, theGroupobject now includes an optionalexpandsToarray, and thegetSupportedFeaturesmethod reports new capability flags for the added group operations and for removing all groups. Existing customGroupsServiceimplementations must be updated accordingly.The
POST /groupsendpoint of the io.Manager Server REST API now returns status code400when a group with the samenamealready exists; previously, posting the name of an existing group succeeded without changing it. Creating a group is now strict on bothPOST /groupsand the newPOST /v2/groups/add. To create or update a group, usePOST /v2/groups; to update an existing group, usePOST /v2/groups/update.New Features
Added the
GET /api/v2/commands/{id}/fileendpoint of the io.Manager Server REST API that responds with the command result file's own bytes.Added the
GET /api/v2/server/logendpoint of the io.Manager Server REST API that responds with a zip archive of every log file the logging configuration writes, including the rotated backups. Use theincludeBackupsquery parameter to leave the rotated backups out, and thefileNamesquery parameter to limit the archive to specific log files.Added product-aware sessions and command descriptions for io.Connect Desktop and io.Connect Browser.
Added
productandproductVersiondatabase columns to thesessionstable and aproductdatabase column to thecommands_for_versiontable, whose uniqueness constraint now coversproductandversiontogether (for PostgreSQL and Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must create the columns and re-key the existing rows manually by running the following scripts.
For PostgreSQL:
ALTER TABLE sessions ADD COLUMN IF NOT EXISTS product VARCHAR(255), -- The io.Connect product that opened the session. ADD COLUMN IF NOT EXISTS "productVersion" VARCHAR(255); -- Version of that product. Determines which commands the session supports. UPDATE sessions SET product = CASE WHEN glue->'core'->'platform'->>'version' IS NOT NULL OR glue->>'version' LIKE 'io.connect.browser-%' THEN 'ioCB' ELSE 'ioCD' END, "productVersion" = CASE WHEN glue->'core'->'platform'->>'version' IS NOT NULL THEN glue->'core'->'platform'->>'version' WHEN glue->>'version' LIKE 'io.connect.browser-%' THEN substring(glue->>'version' from 20) ELSE glue->>'version' END; ALTER TABLE sessions ALTER COLUMN product SET NOT NULL, ALTER COLUMN "productVersion" SET NOT NULL; ALTER TABLE commands_for_version ADD COLUMN IF NOT EXISTS product VARCHAR(255); -- The io.Connect product. Unique together with the version. ALTER TABLE commands_for_version DROP CONSTRAINT IF EXISTS commands_for_version_version_unique; -- Only rows that have not been re-keyed yet: product is derived from version while version -- itself is rewritten, so a second pass would classify an already-re-keyed row as ioCD. UPDATE commands_for_version SET product = CASE WHEN version LIKE 'io.connect.browser-%' THEN 'ioCB' ELSE 'ioCD' END, version = CASE WHEN version LIKE 'io.connect.browser-%' THEN substring(version from 20) ELSE version END WHERE product IS NULL; ALTER TABLE commands_for_version ALTER COLUMN product SET NOT NULL; ALTER TABLE commands_for_version ADD CONSTRAINT commands_for_version_product_version_unique UNIQUE (product, version);For Microsoft SQL Server:
IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[sessions]') AND name = 'product' ) ALTER TABLE sessions ADD product NVARCHAR(255) NULL; -- The io.Connect product that opened the session. GO IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[sessions]') AND name = 'productVersion' ) ALTER TABLE sessions ADD "productVersion" NVARCHAR(255) NULL; -- Version of that product. Determines which commands the session supports. GO UPDATE sessions SET product = CASE WHEN JSON_VALUE(glue, '$.core.platform.version') IS NOT NULL OR JSON_VALUE(glue, '$.version') LIKE 'io.connect.browser-%' THEN 'ioCB' ELSE 'ioCD' END, "productVersion" = CASE WHEN JSON_VALUE(glue, '$.core.platform.version') IS NOT NULL THEN JSON_VALUE(glue, '$.core.platform.version') WHEN JSON_VALUE(glue, '$.version') LIKE 'io.connect.browser-%' THEN SUBSTRING( JSON_VALUE(glue, '$.version'), 20, LEN(JSON_VALUE(glue, '$.version')) ) ELSE JSON_VALUE(glue, '$.version') END; ALTER TABLE sessions ALTER COLUMN product NVARCHAR(255) NOT NULL; ALTER TABLE sessions ALTER COLUMN "productVersion" NVARCHAR(255) NOT NULL; IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[commands_for_version]') AND name = 'product' ) ALTER TABLE commands_for_version ADD product NVARCHAR(255) NULL; -- The io.Connect product. Unique together with the version. GO ALTER TABLE commands_for_version DROP CONSTRAINT IF EXISTS commands_for_version_version_unique; -- Only rows that have not been re-keyed yet: product is derived from version while version -- itself is rewritten, so a second pass would classify an already-re-keyed row as ioCD. UPDATE commands_for_version SET product = CASE WHEN version LIKE 'io.connect.browser-%' THEN 'ioCB' ELSE 'ioCD' END, version = CASE WHEN version LIKE 'io.connect.browser-%' THEN SUBSTRING(version, 20, LEN(version)) ELSE version END WHERE product IS NULL; ALTER TABLE commands_for_version ALTER COLUMN product NVARCHAR(255) NOT NULL; ALTER TABLE commands_for_version ADD CONSTRAINT commands_for_version_product_version_unique UNIQUE (product, version);
Added support for PostgreSQL 18. io.Manager now requires PostgreSQL 14, 15, 16, 17, or 18.
Added support for Microsoft SQL Server 2025. io.Manager now requires Microsoft SQL Server 2016 SP3, 2017, 2019, 2022, or 2025.
Added a
dbConnectivityQueryproperty to theHealthEndpointsConfigobject. Use this property to specify the SQL query executed by the database connectivity health check when using PostgreSQL or Microsoft SQL Server. Configure a read-only query that accesses the database objects and permissions required by your deployment. The query is executed by theGET /db-connectivityendpoint and any custom database connectivity endpoint. It defaults to"select 1".
Property Type Description dbConnectivityQuerystringSQL query executed by the database connectivity health check when using PostgreSQL or Microsoft SQL Server. Defaults to "select 1".The following example demonstrates how to verify that the health check can access the
userstable:import { start } from "@interopio/manager"; const config = { healthEndpoints: { dbConnectivityQuery: "select id from users where id = '__io_manager_health_check__'" } }; const server = await start(config);You can also use the following environment variable:
Environment Variable Description API_HEALTH_ENDPOINTS_DB_CONNECTIVITY_QUERYSQL query executed by the database connectivity health check when using PostgreSQL or Microsoft SQL Server. Defaults to select 1.API_HEALTH_ENDPOINTS_DB_CONNECTIVITY_QUERY="select id from users where id = '__io_manager_health_check__'"
Added a granular permission-group system to the io.Manager Server REST API. Endpoints are gated by per-resource, per-action permission groups (e.g.
IO_MANAGER:APPS:READ,IO_MANAGER:LAYOUTS:WRITE) instead of a single admin group. For the full list of built-in permission groups and the default groups, see Authorization.Added the
auth_extra_groupstop-level key in the configuration object for initializing the io.Manager Server. Use this property to define additional groups that expand into granular permission groups or other groups. The supplied entries are merged with the built-in default groups, which take precedence over an entry with the samename. For the full list of available permission groups and the default groups, see Authorization.
Property Type Description auth_extra_groupsGroup[]List of additional groups. Accepts an array of Groupobjects.The following example demonstrates how to configure custom groups:
import { start } from "@interopio/manager"; const config = { auth_extra_groups: [ { name: "apps-manager", description: "Can read and write apps.", expandsTo: ["IO_MANAGER:APPS:READ", "IO_MANAGER:APPS:WRITE", "IO_MANAGER:SCHEMAS:READ"] }, { name: "apps-layouts-manager", description: "Can read and write apps and layouts.", expandsTo: ["apps-manager", "IO_MANAGER:LAYOUTS:READ", "IO_MANAGER:LAYOUTS:WRITE"] }, { name: "read-only", description: "Can read all resources.", expandsTo: ["IO_MANAGER:APPS:READ", "IO_MANAGER:AUDITS:READ", "IO_MANAGER:COMMANDS:READ", "IO_MANAGER:CRASHES:READ", "IO_MANAGER:FEEDBACKS:READ", "IO_MANAGER:GROUPS:READ", "IO_MANAGER:LAYOUTS:READ", "IO_MANAGER:MACHINES:READ", "IO_MANAGER:PREFS:READ", "IO_MANAGER:SCHEMAS:READ", "IO_MANAGER:SESSIONS:READ", "IO_MANAGER:SYSTEM:READ", "IO_MANAGER:SYSTEM_CONFIG:READ", "IO_MANAGER:USERS:READ"] } ] }; const server = await start(config);You can also use the following environment variable:
Environment Variable Description API_AUTH_EXTRA_GROUPSJSON-encoded array of custom group definitions. Each entry must have a name, and may have anexpandsToarray and adescription.The following example demonstrates how to configure custom groups via environment variables:
API_AUTH_EXTRA_GROUPS=[ { "name": "apps-manager", "description": "Can read and write apps.", "expandsTo": ["IO_MANAGER:APPS:READ", "IO_MANAGER:APPS:WRITE", "IO_MANAGER:SCHEMAS:READ"] }, { "name": "apps-layouts-manager", "description": "Can read and write apps and layouts.", "expandsTo": ["apps-manager", "IO_MANAGER:LAYOUTS:READ", "IO_MANAGER:LAYOUTS:WRITE"] } ]
- Added the
advancedLayoutstop-level key in the configuration object for initializing the io.Manager Server. Use this property to switch io.Connect platform clients between legacy and advanced Layouts and to restrict who can save advanced Layouts withaccessLevelset to"shared"or"public". WhenadvancedLayouts.enabledis set totrue, the server serves advanced Layouts; whenfalse(default), it serves legacy Layouts. Using advanced Layouts requires io.Connect Desktop 10.5 (unreleased) or later as a platform client.
Property Type Description enabledbooleanIf true, the io.Manager Server serves advanced Layouts to io.Connect platform clients instead of legacy Layouts. Defaults tofalse.sharingRequiredGroupstringName of a group whose members are allowed to save advanced Layouts with accessLevelset to"shared"or"public". Membership in nested groups is honored. Saving advanced Layouts withaccessLevelset to"private"is never restricted. When omitted, any authenticated user may share or publish advanced Layouts.The following example demonstrates how to enable advanced Layouts and restrict Layout sharing to members of a
"layout-sharers"group:import { start } from "@interopio/manager"; const config = { advancedLayouts: { // Serve advanced Layouts to io.Connect platform clients. enabled: true, // Only members of the `layout-sharers` group will be allowed to save // advanced Layouts with `accessLevel` set to `"shared"` or `"public"`. sharingRequiredGroup: "layout-sharers" } }; const server = await start(config);You can also use the following environment variables:
Environment Variable Description API_ADVANCED_LAYOUTS_ENABLEDIf true, the io.Manager Server serves advanced Layouts to io.Connect platform clients instead of legacy Layouts. Defaults tofalse.API_ADVANCED_LAYOUTS_SHARING_REQUIRED_GROUPName of a group whose members are allowed to save advanced Layouts with accessLevelset tosharedorpublic. Membership in nested groups is honored. Saving advanced Layouts withaccessLevelset toprivateis never restricted. When omitted, any authenticated user may share or publish advanced Layouts.The following example demonstrates how to enable advanced Layouts and restrict Layout sharing to members of a
layout-sharersgroup via environment variables:API_ADVANCED_LAYOUTS_ENABLED=true API_ADVANCED_LAYOUTS_SHARING_REQUIRED_GROUP=layout-sharersThe
GET /v2/server/infoendpoint response now includes anadvancedLayoutsEnabledfield. Use it to detect from io.Connect platform clients whether the connected io.Manager Server is serving advanced Layouts or legacy Layouts.
- Added the
/advancedLayoutsendpoints to the io.Manager Server REST API. Use them to read, create, update, and delete advanced Layouts, and to check a Layout identity against the uniqueness rule before saving. The read endpoints require theIO_MANAGER:LAYOUTS:READpermission group and the write endpoints requireIO_MANAGER:LAYOUTS:WRITE. Using advanced Layouts requires io.Connect Desktop 10.5 (unreleased) or later as a platform client. For the full request and response shapes, see the Swagger UI.
Endpoint Description GET /advancedLayoutsLists advanced Layouts, with support for filtering, grouping, sorting, and paging. GET /advancedLayouts/{id}Returns the advanced Layout with the given id.POST /advancedLayoutsCreates an advanced Layout, or updates it if one with the same idalready exists.POST /advancedLayouts/addCreates an advanced Layout. Returns 400when one with the samenameandtypealready exists, so an existing Layout is never overwritten.POST /advancedLayouts/updateUpdates the advanced Layout with the given id. Returns404when no Layout with thatidexists.POST /advancedLayouts/check-conflictReports whether saving a Layout with the given name,type, and access level would collide with an existing Layout, before the save is submitted.DELETE /advancedLayouts/{id}Deletes the advanced Layout with the given id.
Added a one-time migration of legacy Layouts to advanced Layouts, available only when advanced Layouts are enabled. Use the new
GET /advancedLayouts/migration/statusendpoint to review the migration status, the newGET /advancedLayouts/migration/layoutsendpoint to review the legacy Layouts a run would migrate and the advanced access each will receive, and the newPOST /advancedLayouts/migration/runendpoint to run the migration. All three endpoints require theIO_MANAGER:LAYOUTS:WRITEpermission group. The migration can be completed only once - a run that leaves nothing to migrate and reports no failures locks it permanently.Added a
migrationproperty to theadvancedLayoutsconfiguration object. Use this property to control how the Layout migration runs.
Property Type Description claimStalenessnumberTime in milliseconds after which an abandoned Layout migration run may be taken over by a new run. Must be a finite number greater than zero. Defaults to 600000(10 minutes).pageSizenumberNumber of legacy Layouts a migration run reads and writes at a time. Lower values reduce the run's memory use and higher values reduce the number of database round trips. Must be an integer greater than zero. Defaults to 1000.You can also use the following environment variables:
Environment Variable Description API_ADVANCED_LAYOUTS_MIGRATION_CLAIM_STALENESSTime in milliseconds after which an abandoned Layout migration run may be taken over by a new run. Must be a finite number greater than zero. Defaults to 600000(10 minutes).API_ADVANCED_LAYOUTS_MIGRATION_PAGE_SIZENumber of legacy Layouts a migration run reads and writes at a time. Lower values reduce the run's memory use and higher values reduce the number of database round trips. Must be an integer greater than zero. Defaults to 1000.
- Added a
layouts_advanceddatabase table for storing advanced Layouts (for PostgreSQL and Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must create the
layouts_advancedtable manually by running the following scripts.For PostgreSQL:
-- Layouts saved by an io.Connect platform, with per-entity access control. CREATE TABLE IF NOT EXISTS layouts_advanced ( layouts_advanced_id SERIAL PRIMARY KEY, -- Primary key. Auto-assigned by the database and not used to identify the row outside it. id VARCHAR(255) NOT NULL, -- Public identifier of the layout. Unique. type VARCHAR(255) NOT NULL, -- Kind of layout, for example 'Global' or 'Workspace'. name VARCHAR(255) NOT NULL, -- Name of the layout. Unique per type per owner while private, and unique per type across all owners once shared or public. disabled BOOLEAN NOT NULL, -- Whether the layout is withheld from all users. "accessLevel" VARCHAR(255) NOT NULL, -- Who can reach the layout: 'private', 'shared' or 'public'. "owner" VARCHAR(255) NOT NULL, -- User the layout belongs to. "accessInfo" JSON NULL, definition JSON NOT NULL, "createdBy" VARCHAR(255) NOT NULL, -- User that created the layout. "createdOn" BIGINT NOT NULL, -- Creation time. Epoch milliseconds (UTC). "lastModifiedBy" VARCHAR(255) NULL, -- User that last modified the layout. "lastModifiedOn" BIGINT NULL, -- Time of the last modification. Epoch milliseconds (UTC). CONSTRAINT layouts_advanced_id_unique UNIQUE (id) ); CREATE UNIQUE INDEX IF NOT EXISTS layouts_advanced__name__type__owner__unique ON layouts_advanced (name, type, owner) WHERE "accessLevel" = 'private'; CREATE UNIQUE INDEX IF NOT EXISTS layouts_advanced__name__type__nonprivate__unique ON layouts_advanced (name, type) WHERE "accessLevel" IN ('shared', 'public');For Microsoft SQL Server:
-- Layouts saved by an io.Connect platform, with per-entity access control. IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='layouts_advanced' AND xtype='U') CREATE TABLE layouts_advanced ( layouts_advanced_id INT IDENTITY PRIMARY KEY, -- Primary key. Auto-assigned by the database and not used to identify the row outside it. id NVARCHAR(255) NOT NULL, -- Public identifier of the layout. Unique. type NVARCHAR(255) NOT NULL, -- Kind of layout, for example 'Global' or 'Workspace'. name NVARCHAR(255) NOT NULL, -- Name of the layout. Unique per type per owner while private, and unique per type across all owners once shared or public. disabled BIT NOT NULL, -- Whether the layout is withheld from all users. Boolean, stored as 0 or 1. accessLevel NVARCHAR(255) NOT NULL, -- Who can reach the layout: 'private', 'shared' or 'public'. owner NVARCHAR(255) NOT NULL, -- User the layout belongs to. "accessInfo" NVARCHAR(MAX) NULL, -- Users and groups granted access, with the level granted to each. Present only for shared layouts. JSON, stored as text. definition NVARCHAR(MAX) NOT NULL, -- The layout payload as saved by the io.Connect platform. JSON, stored as text. "createdBy" NVARCHAR(255) NOT NULL, -- User that created the layout. "createdOn" BIGINT NOT NULL, -- Creation time. Epoch milliseconds (UTC). "lastModifiedBy" NVARCHAR(255) NULL, -- User that last modified the layout. "lastModifiedOn" BIGINT NULL, -- Time of the last modification. Epoch milliseconds (UTC). CONSTRAINT layouts_advanced_id_unique UNIQUE (id) ); IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'layouts_advanced__name__type__owner__unique' AND object_id = OBJECT_ID('layouts_advanced')) CREATE UNIQUE INDEX layouts_advanced__name__type__owner__unique ON layouts_advanced (name, type, owner) WHERE accessLevel = 'private'; IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'layouts_advanced__name__type__nonprivate__unique' AND object_id = OBJECT_ID('layouts_advanced')) CREATE UNIQUE INDEX layouts_advanced__name__type__nonprivate__unique ON layouts_advanced (name, type) WHERE accessLevel IN ('shared', 'public');
- Added an
othersdatabase column to theuserstable (for PostgreSQL and Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must create the
otherscolumn manually by running the following scripts.For PostgreSQL:
ALTER TABLE users ADD COLUMN IF NOT EXISTS others JSONB NULL; -- Per-user timestamps that do not have a column of their own. JSON.For Microsoft SQL Server:
IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[users]') AND name = 'others' ) ALTER TABLE users ADD others NVARCHAR(MAX) NULL; -- Per-user timestamps that do not have a column of their own. JSON, stored as text.
- Added
descriptionandexpandsTodatabase columns to thegroupstable (for PostgreSQL and Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must create the
descriptionandexpandsTocolumns manually by running the following scripts.For PostgreSQL:
ALTER TABLE groups ADD COLUMN IF NOT EXISTS description TEXT NULL, -- Description of the group. ADD COLUMN IF NOT EXISTS "expandsTo" VARCHAR(255)[] NOT NULL DEFAULT '{}'::varchar[]; -- Groups this group also grants membership of. Empty when it expands into no others. Array of strings.For Microsoft SQL Server:
IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[groups]') AND name = 'description' ) ALTER TABLE groups ADD description NVARCHAR(MAX) NULL; -- Description of the group. IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[groups]') AND name = 'expandsTo' ) ALTER TABLE groups ADD expandsTo NVARCHAR(MAX) NOT NULL CONSTRAINT DF_groups_expandsTo DEFAULT '[]'; -- Groups this group also grants membership of. Empty when it expands into no others. JSON array of strings, stored as text.
- Added a
system_statedatabase table for storing server-managed system state, such as the Layout-migration status (for PostgreSQL and Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must create the
system_statetable manually by running the following scripts.For PostgreSQL:
-- Server-wide state shared by every io.Manager instance, one row per named entry. CREATE TABLE IF NOT EXISTS system_state ( system_state_id SERIAL PRIMARY KEY, -- Primary key. Auto-assigned by the database and not used to identify the row outside it. name VARCHAR(255) NOT NULL, -- Name of the entry. Unique. value JSONB NOT NULL, -- The entry value. JSON. version INT NOT NULL, -- Revision of the entry, raised on every write so concurrent instances cannot overwrite each other. CONSTRAINT system_state_name_unique UNIQUE (name) );For Microsoft SQL Server:
-- Server-wide state shared by every io.Manager instance, one row per named entry. IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='system_state' AND xtype='U') CREATE TABLE system_state ( system_state_id INT IDENTITY PRIMARY KEY, -- Primary key. Auto-assigned by the database and not used to identify the row outside it. name NVARCHAR(255) NOT NULL, -- Name of the entry. Unique. value NVARCHAR(MAX) NOT NULL, -- The entry value. JSON, stored as text. version INT NOT NULL, -- Revision of the entry, raised on every write so concurrent instances cannot overwrite each other. CONSTRAINT system_state_name_unique UNIQUE (name) );
- Added a
migrateddatabase column to thelayoutstable (for PostgreSQL and Microsoft SQL Server only). The Layout migration uses it to mark legacy Layouts that have already been migrated to advanced Layouts.⚠️ Note that users who don't use automatic schema migration must create the
migratedcolumn manually by running the following scripts.For PostgreSQL:
ALTER TABLE layouts ADD COLUMN IF NOT EXISTS migrated BOOLEAN NULL; -- Whether this layout has already been migrated to the layouts_advanced table.For Microsoft SQL Server:
IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[layouts]') AND name = 'migrated' ) ALTER TABLE layouts ADD migrated BIT; -- Whether this layout has already been migrated to the layouts_advanced table. Boolean, stored as 0 or 1.
Added an optional
configKeysquery parameter to theGET /systemConfigendpoint of the io.Manager Server REST API. Use this parameter to narrow which config-file names appear in each entry'sconfigsmap, reducing the response size when only a subset of config files is needed.Added a user-facing REST API surface at
/v2/user/*to the io.Manager Server for io.Connect platform clients, consumed by the newClientAPIV2class in@interopio/manager-api.Added the
POST /v2/user/query-usersandPOST /v2/user/query-groupsendpoints for looking up users and groups by name. Use them from io.Connect platform clients via the newio.manager.users.query()andio.manager.groups.query()methods.Added the
POST /v2/user/layouts/check-conflictandPOST /v2/user/advancedLayouts/check-conflictendpoints for checking whether saving a Layout with a given identity would collide with an existing one. Use them from io.Connect platform clients via the newio.manager.layouts.checkConflict()method to prompt the user before submitting a save - for example, to ask whether to overwrite an existing Layout or to pick a different name - instead of catching a failure after the fact.Added an admin-facing REST API surface at
/v2/groups/*to the io.Manager Server for reading, creating, updating, and deleting stored groups, and for expanding a set of group names into the full set of groups and granular permission groups they map to. Read operations require theIO_MANAGER:GROUPS:READpermission group and write operations require theIO_MANAGER:GROUPS:WRITEpermission group. The new surface is consumed by the newGroupsV2class in@interopio/manager-api.Added a
transactionsproperty to theMongoStoreConfigobject. Use this property to control whether the io.Manager Server uses MongoDB multi-document transactions, which require MongoDB to be deployed as a replica set or a sharded cluster.
Property Type Description transactions"disabled"|"required"|"autodetect"Whether to use MongoDB multi-document transactions. Set to "required"to prevent the server from starting when the MongoDB deployment doesn't support transactions, or to"disabled"to never use transactions. Defaults to"autodetect"- transactions are used when the deployment supports them, otherwise the server logs a warning and runs without transactions.The following example demonstrates how to configure the transactions mode:
import { start } from "@interopio/manager"; const config = { store: { type: "mongo", connection: "mongodb://localhost:27017/my_db", // Refuse to start unless the MongoDB deployment supports transactions. transactions: "required" } }; const server = await start(config);You can also use the following environment variable:
Environment Variable Description API_STORE_MONGO_TRANSACTIONSWhether to use MongoDB multi-document transactions. Defaults to autodetect.API_STORE_MONGO_TRANSACTIONS=required
- Added
migrationRetriesandmigrationRetryDelayMsproperties to thePostgreSQLStoreConfigandMSSQLStoreConfigobjects. Use these properties to control how store initialization - creating the database, creating the schema and running the migration scripts - is retried after a transient failure, such as another server instance initializing the same database concurrently. The error of the final attempt is propagated, so a misconfigured store still fails to start.
Property Type Description migrationRetriesnumberHow many times store initialization is retried after a transient failure. Defaults to 3.migrationRetryDelayMsnumberThe delay in milliseconds between retry attempts. Defaults to 1000.You can also use the following environment variables:
Environment Variable Description API_STORE_POSTGRESQL_MIGRATION_RETRIESHow many times store initialization is retried after a transient failure. Defaults to 3.API_STORE_POSTGRESQL_MIGRATION_RETRY_DELAY_MSThe delay in milliseconds between retry attempts. Defaults to 1000.API_STORE_MSSQL_MIGRATION_RETRIESHow many times store initialization is retried after a transient failure. Defaults to 3.API_STORE_MSSQL_MIGRATION_RETRY_DELAY_MSThe delay in milliseconds between retry attempts. Defaults to 1000.
- Added
transactionRetries,transactionRetryDelayMs, andtransactionIsolationproperties to thePostgreSQLStoreConfigandMSSQLStoreConfigobjects. UsetransactionRetriesandtransactionRetryDelayMsto control how database transactions and standalone reads are retried after a transient failure, andtransactionIsolationto choose the isolation level for the database transactions the server opens.
Property Type Description transactionIsolationstringThe isolation level for the database transactions the server opens. Accepts "database-default","read-committed","repeatable-read"(PostgreSQL only),"snapshot"(Microsoft SQL Server only), or"serializable"as a value."database-default"leaves the database's own default isolation level in effect. Defaults to"database-default".transactionRetriesnumberHow many times a database transaction, or a standalone read, is re-run after a transient failure. Set to 0to disable the retry. Defaults to3.transactionRetryDelayMsnumberThe base delay in milliseconds between retry attempts. The actual delay is randomized and increases with each retry. Defaults to 100.⚠️ Note that
"snapshot"requires the database to haveALLOW_SNAPSHOT_ISOLATIONenabled - otherwise, the server won't start.You can also use the following environment variables:
Environment Variable Description API_STORE_POSTGRESQL_TRANSACTION_ISOLATIONThe isolation level for the database transactions the server opens. Defaults to database-default.API_STORE_POSTGRESQL_TRANSACTION_RETRIESHow many times a database transaction, or a standalone read, is re-run after a transient failure. Defaults to 3.API_STORE_POSTGRESQL_TRANSACTION_RETRY_DELAY_MSThe base delay in milliseconds between retry attempts. The actual delay is randomized and increases with each retry. Defaults to 100.API_STORE_MSSQL_TRANSACTION_ISOLATIONThe isolation level for the database transactions the server opens. Defaults to database-default.API_STORE_MSSQL_TRANSACTION_RETRIESHow many times a database transaction, or a standalone read, is re-run after a transient failure. Defaults to 3.API_STORE_MSSQL_TRANSACTION_RETRY_DELAY_MSThe base delay in milliseconds between retry attempts. The actual delay is randomized and increases with each retry. Defaults to 100.
Added two OpenTelemetry metrics for observing database resilience:
"io_manager.db.transaction.duration"- the duration of the database transactions the server opens - and"io_manager.db.operation.retries"- the number of transient-failure retries of database transactions and standalone reads.Added an OpenTelemetry trace span named
"db.transaction"for each database transaction the server opens, recording an event for every transient-failure retry of that transaction.Deprecated Endpoints
The following REST API endpoints have been deprecated:
Deprecated Endpoint New Endpoint GET /commands/{id}/fileUse GET /v2/commands/{id}/fileinstead.GET /groupsUse GET /v2/groupsinstead.POST /groupsUse POST /v2/groups/addfor a strict insert, orPOST /v2/groupsfor an upsert (create or update).DELETE /groups/{name}Use DELETE /v2/groups/{name}instead.GET /server/logUse GET /v2/server/loginstead.Improvements & Bug Fixes
- On Microsoft SQL Server, all
VARCHAR(255)columns are nowNVARCHAR(255), so usernames, Layout names, and every other text field store the full Unicode range. Previously, a character outside the code page of the database collation, such as Cyrillic or Greek, was stored as?.⚠️ Note that users who don't use automatic schema migration must convert the columns manually by running the following script. Each unique constraint is dropped and recreated around the conversion, because a column can't be altered while a constraint references it.
ALTER TABLE app DROP CONSTRAINT app_name_unique; ALTER TABLE audit DROP CONSTRAINT audit_id_unique; ALTER TABLE blobs DROP CONSTRAINT blobs_id_unique; ALTER TABLE commands DROP CONSTRAINT commands_id_unique; ALTER TABLE commands_for_version DROP CONSTRAINT commands_for_version_product_version_unique; ALTER TABLE crashes DROP CONSTRAINT crashes_id_unique; ALTER TABLE feedback DROP CONSTRAINT feedback_id_unique; ALTER TABLE groups DROP CONSTRAINT groups_name_unique; ALTER TABLE layouts DROP CONSTRAINT layouts_id_unique; ALTER TABLE layouts DROP CONSTRAINT layouts__name__type__owner__unique; ALTER TABLE machines DROP CONSTRAINT machines_id_unique; ALTER TABLE prefs DROP CONSTRAINT prefs_id_unique; ALTER TABLE prefs DROP CONSTRAINT prefs__app__user__unique; ALTER TABLE sessions DROP CONSTRAINT sessions_id_unique; ALTER TABLE users DROP CONSTRAINT users_id_unique; ALTER TABLE app ALTER COLUMN name NVARCHAR(255) NOT NULL; ALTER TABLE app ALTER COLUMN [createdBy] NVARCHAR(255) NOT NULL; ALTER TABLE app ALTER COLUMN [lastModifiedBy] NVARCHAR(255) NULL; ALTER TABLE audit ALTER COLUMN id NVARCHAR(255) NOT NULL; ALTER TABLE audit ALTER COLUMN [user] NVARCHAR(255) NULL; ALTER TABLE audit ALTER COLUMN parent NVARCHAR(255) NULL; ALTER TABLE audit ALTER COLUMN session NVARCHAR(255) NULL; ALTER TABLE audit ALTER COLUMN server NVARCHAR(255) NULL; ALTER TABLE audit ALTER COLUMN [entityType] NVARCHAR(255) NOT NULL; ALTER TABLE audit ALTER COLUMN [entityId] NVARCHAR(255) NULL; ALTER TABLE audit ALTER COLUMN [entityDisplayName] NVARCHAR(255) NULL; ALTER TABLE audit ALTER COLUMN operation NVARCHAR(255) NOT NULL; ALTER TABLE audit ALTER COLUMN [operationComment] NVARCHAR(255) NULL; ALTER TABLE blobs ALTER COLUMN [type] NVARCHAR(255) NOT NULL; ALTER TABLE blobs ALTER COLUMN id NVARCHAR(255) NOT NULL; ALTER TABLE blobs ALTER COLUMN [fileName] NVARCHAR(255) NOT NULL; ALTER TABLE commands ALTER COLUMN id NVARCHAR(255) NOT NULL; ALTER TABLE commands ALTER COLUMN [user] NVARCHAR(255) NOT NULL; ALTER TABLE commands ALTER COLUMN status NVARCHAR(255) NOT NULL; ALTER TABLE commands ALTER COLUMN session NVARCHAR(255) NOT NULL; ALTER TABLE commands ALTER COLUMN machine NVARCHAR(255) NOT NULL; ALTER TABLE commands ALTER COLUMN [createdBy] NVARCHAR(255) NOT NULL; ALTER TABLE commands ALTER COLUMN command NVARCHAR(255) NOT NULL; ALTER TABLE commands ALTER COLUMN [commandParams] NVARCHAR(255) NULL; ALTER TABLE commands ALTER COLUMN [resultType] NVARCHAR(255) NULL; ALTER TABLE commands_for_version ALTER COLUMN version NVARCHAR(255) NOT NULL; ALTER TABLE crashes ALTER COLUMN id NVARCHAR(255) NOT NULL; ALTER TABLE crashes ALTER COLUMN [user] NVARCHAR(255) NULL; ALTER TABLE feedback ALTER COLUMN id NVARCHAR(255) NOT NULL; ALTER TABLE feedback ALTER COLUMN [user] NVARCHAR(255) NOT NULL; ALTER TABLE feedback ALTER COLUMN session NVARCHAR(255) NOT NULL; ALTER TABLE groups ALTER COLUMN name NVARCHAR(255) NOT NULL; ALTER TABLE layouts ALTER COLUMN id NVARCHAR(255) NOT NULL; ALTER TABLE layouts ALTER COLUMN [type] NVARCHAR(255) NOT NULL; ALTER TABLE layouts ALTER COLUMN name NVARCHAR(255) NOT NULL; ALTER TABLE layouts ALTER COLUMN [owner] NVARCHAR(255) NULL; ALTER TABLE layouts ALTER COLUMN [createdBy] NVARCHAR(255) NOT NULL; ALTER TABLE layouts ALTER COLUMN [lastModifiedBy] NVARCHAR(255) NULL; ALTER TABLE machines ALTER COLUMN id NVARCHAR(255) NOT NULL; ALTER TABLE machines ALTER COLUMN [user] NVARCHAR(255) NOT NULL; ALTER TABLE machines ALTER COLUMN name NVARCHAR(255) NULL; ALTER TABLE prefs ALTER COLUMN id NVARCHAR(255) NOT NULL; ALTER TABLE prefs ALTER COLUMN app NVARCHAR(255) NOT NULL; ALTER TABLE prefs ALTER COLUMN [user] NVARCHAR(255) NOT NULL; ALTER TABLE sessions ALTER COLUMN id NVARCHAR(255) NOT NULL; ALTER TABLE sessions ALTER COLUMN machine NVARCHAR(255) NOT NULL; ALTER TABLE sessions ALTER COLUMN [user] NVARCHAR(255) NOT NULL; ALTER TABLE sessions ALTER COLUMN [closeReason] NVARCHAR(255) NULL; ALTER TABLE users ALTER COLUMN id NVARCHAR(255) NOT NULL; ALTER TABLE users ALTER COLUMN email NVARCHAR(255) NULL; ALTER TABLE users ALTER COLUMN password NVARCHAR(255) NULL; ALTER TABLE users ALTER COLUMN [firstName] NVARCHAR(255) NULL; ALTER TABLE users ALTER COLUMN [lastName] NVARCHAR(255) NULL; ALTER TABLE app ADD CONSTRAINT app_name_unique UNIQUE (name); ALTER TABLE audit ADD CONSTRAINT audit_id_unique UNIQUE (id); ALTER TABLE blobs ADD CONSTRAINT blobs_id_unique UNIQUE (id); ALTER TABLE commands ADD CONSTRAINT commands_id_unique UNIQUE (id); ALTER TABLE commands_for_version ADD CONSTRAINT commands_for_version_product_version_unique UNIQUE (product, version); ALTER TABLE crashes ADD CONSTRAINT crashes_id_unique UNIQUE (id); ALTER TABLE feedback ADD CONSTRAINT feedback_id_unique UNIQUE (id); ALTER TABLE groups ADD CONSTRAINT groups_name_unique UNIQUE (name); ALTER TABLE layouts ADD CONSTRAINT layouts_id_unique UNIQUE (id); ALTER TABLE layouts ADD CONSTRAINT layouts__name__type__owner__unique UNIQUE ([name], [type], [owner]); ALTER TABLE machines ADD CONSTRAINT machines_id_unique UNIQUE (id); ALTER TABLE prefs ADD CONSTRAINT prefs_id_unique UNIQUE (id); ALTER TABLE prefs ADD CONSTRAINT prefs__app__user__unique UNIQUE ([app], [user]); ALTER TABLE sessions ADD CONSTRAINT sessions_id_unique UNIQUE (id); ALTER TABLE users ADD CONSTRAINT users_id_unique UNIQUE (id);
- Added database indexes for every column a username is resolved by -
users.id,layouts.owner,prefs.user, andmachines.user- in both a case-folded and an exact form, so that both settings ofusername_case_sensitiveuse an index instead of scanning the table. On Microsoft SQL Server, the case-folded form is a persisted computed column with an index on it, because Microsoft SQL Server has no expression indexes. On MongoDB, the case-folded form is an index declaring the case-insensitive collation the comparison uses.⚠️ Note that users who don't use automatic schema migration must create the indexes manually by running the following scripts. On MongoDB, the indexes are created by the server on startup and don't need any manual step.
For PostgreSQL:
CREATE INDEX IF NOT EXISTS users__id__lower ON users (lower(id)); CREATE INDEX IF NOT EXISTS layouts__owner__lower ON layouts (lower("owner")); CREATE INDEX IF NOT EXISTS layouts__owner ON layouts ("owner"); CREATE INDEX IF NOT EXISTS prefs__user__lower__app ON prefs (lower("user"), app); CREATE INDEX IF NOT EXISTS prefs__user ON prefs ("user"); CREATE INDEX IF NOT EXISTS machines__user__lower ON machines (lower("user")); CREATE INDEX IF NOT EXISTS machines__user ON machines ("user");For Microsoft SQL Server:
IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[users]') AND name = 'id_lower' ) ALTER TABLE users ADD id_lower AS LOWER(id) PERSISTED; -- The identifier, lowercased, for resolving a username when username_case_sensitive is false. Derived by the database. GO IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[layouts]') AND name = 'owner_lower' ) ALTER TABLE layouts ADD owner_lower AS LOWER([owner]) PERSISTED; -- The owner, lowercased, for resolving a username when username_case_sensitive is false. Derived by the database. GO IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[prefs]') AND name = 'user_lower' ) ALTER TABLE prefs ADD user_lower AS LOWER([user]) PERSISTED; -- The user, lowercased, for resolving a username when username_case_sensitive is false. Derived by the database. GO IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[machines]') AND name = 'user_lower' ) ALTER TABLE machines ADD user_lower AS LOWER([user]) PERSISTED; -- The user, lowercased, for resolving a username when username_case_sensitive is false. Derived by the database. GO IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'users__id__lower' AND object_id = OBJECT_ID('users')) CREATE INDEX users__id__lower ON users (id_lower); IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'layouts__owner__lower' AND object_id = OBJECT_ID('layouts')) CREATE INDEX layouts__owner__lower ON layouts (owner_lower); IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'layouts__owner' AND object_id = OBJECT_ID('layouts')) CREATE INDEX layouts__owner ON layouts ([owner]); IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'prefs__user__lower__app' AND object_id = OBJECT_ID('prefs')) CREATE INDEX prefs__user__lower__app ON prefs (user_lower, app); IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'prefs__user' AND object_id = OBJECT_ID('prefs')) CREATE INDEX prefs__user ON prefs ([user]); IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'machines__user__lower' AND object_id = OBJECT_ID('machines')) CREATE INDEX machines__user__lower ON machines (user_lower); IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'machines__user' AND object_id = OBJECT_ID('machines')) CREATE INDEX machines__user ON machines ([user]);⚠️ Note that on Microsoft SQL Server, indexing a computed column makes the
QUOTED_IDENTIFIERsession option mandatory for everyINSERT,UPDATE, andDELETEagainst theusers,layouts,prefs, andmachinestables. The io.Manager Server and current database drivers set it automatically, but tooling that writes to these tables directly may not -sqlcmd, for example, requires the-Iflag. A session without it fails with"DELETE failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'".
Fixed a bug where the
traceContextfield of commands was returned as a JSON-encoded string instead of an object when io.Manager was running against Microsoft SQL Server, causing io.Connect platform clients to fail response validation and be unable to open a session when OpenTelemetry tracing was enabled.Fixed an inconsistency where the
resultAt,resultData, andtraceContextfields of a not-yet-completed command serialized differently across database backends. These fields are now consistently omitted until the command completes, on all supported databases.The
DELETE /api/user/layouts/{id}endpoint of the io.Manager Server REST API now returns status code404when no Layout with the givenidexists; previously, a nonexistent Layout returned403.The
GET /api/summaryendpoint of the io.Manager Server REST API is now available to any authenticated caller and reports only the counts that caller is permitted to see: a dataset is counted when the caller's groups include that dataset's read permission group (e.g.IO_MANAGER:APPS:READfor apps), and is reported as zero otherwise. A caller whose groups includeIO_MANAGER:SYSTEM:READreceives the counts for every dataset.Fixed an inconsistency where Layout IDs weren't enforced as unique on MongoDB, while PostgreSQL and Microsoft SQL Server rejected duplicates. Databases created by an earlier version of io.Manager are updated automatically on startup.
The
POST /usersandPOST /users/importendpoints of the io.Manager Server REST API now store a password only when theauth_methodproperty is set to"basic". A password supplied under any other authentication method is ignored.Fixed a bug where a failed call to
start()left the io.Manager Server's HTTP listener, database connections, and background timers running, so an embedding app couldn't retry the start or shut it down. A failed start now releases them, and an initialization error rejects the returned promise instead of terminating the host process.Improved query performance on Microsoft SQL Server. Queries that filter on a text column, such as the access level of an advanced Layout, now use the available indexes.
Fixed a bug where a request to an endpoint that accepts a file upload - such as submitting feedback or a crash report - could fail with status code
500.Fixed a bug where the
/user/commandsendpoints of the io.Manager Server REST API didn't verify that the requested command or session belongs to the caller. Such requests now return status code403.Fixed a bug where the
POST /user/layoutsandPOST /v2/user/layoutsendpoints of the io.Manager Server REST API, and their bulk counterparts, didn't verify that a Layout named by its ID is one the caller is allowed to save over. Such requests now return status code404.Fixed a bug where the
POST /user/layouts/defaultandPOST /v2/user/layouts/defaultendpoints of the io.Manager Server REST API didn't verify that the requested Layout is visible to the caller. Such requests now return status code403.Fixed a bug where the
POST /v2/user/query-usersandPOST /v2/user/query-groupsendpoints of the io.Manager Server REST API ran an unbounded search for very short terms. A search term shorter than three characters now returns an empty result set.Added an
encodingdatabase column to theblobstable (for PostgreSQL and Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must create the
encodingcolumn and mark the existing rows manually by running the following scripts.For PostgreSQL:
ALTER TABLE blobs ADD COLUMN IF NOT EXISTS encoding VARCHAR(20); -- Encoding of the content: "raw" when it is the file's own bytes, "base64" when it is those bytes base64-encoded as text. Absent on content stored before the encoding was recorded. -- Only rows that predate the column are NULL, so re-running this script never -- reclassifies files stored after the upgrade. UPDATE blobs SET encoding = 'base64' WHERE type = 'command_result' AND encoding IS NULL;For Microsoft SQL Server:
IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[blobs]') AND name = 'encoding' ) ALTER TABLE blobs ADD encoding NVARCHAR(20) NULL; -- Encoding of the content: "raw" when it is the file's own bytes, "base64" when it is those bytes base64-encoded as text. Absent on content stored before the encoding was recorded. GO -- Only rows that predate the column are NULL, so re-running this script never -- reclassifies files stored after the upgrade. UPDATE blobs SET encoding = 'base64' WHERE type = 'command_result' AND encoding IS NULL;
Fixed a bug where the
DELETE /groups/{name}endpoint of the io.Manager Server REST API called a custom Groups service'sremoveGroupmethod even when the service reports thecanRemoveGroupcapability asfalse, so a service that leaves the method unimplemented failed with status code500. Such requests now return status code501.The
DELETE /groupsendpoint of the io.Manager Server REST API now returns status code501when a custom Groups service doesn't report thecanRemoveAllcapability.The io.Manager Server now calls a custom Groups service's
getUserGroupsmethod only when the service reports thecanGetUserGroupscapability astrue. A service that resolves the groups a user belongs to must report that capability; otherwise those groups don't contribute to a user's permissions, and theGET /users/{name}/groupsendpoint of the io.Manager Server REST API returns status code501.Dependency Changes
The following new dependencies have been added to the package:
@node-rs/xxhashversion^1.7.6@scalar/openapi-typesversion^0.9.1archiverversion^8.0.0The following dependencies have been removed from the package:
lodashThe following dependencies have been updated:
@interopio/schemasfrom version^9.7.0to^10.0.0@nestjs/swaggerfrom version11.2.3to^11.2.3tediousfrom version^19.1.3to^20.0.0
2.0
2.1.1
Release date: 22.05.2026
Improvements & Bug Fixes
- Fixed a bug where the
traceContextfield of each io.Manager command was returned as a JSON-encoded string instead of an object when using Microsoft SQL Server as a database, which caused the io.Connect platform to fail response validation and be unable to open a session when OpenTelemetry tracing is enabled.
2.1.0
Release date: 30.01.2026
Breaking Changes
- Dropped support for PostgreSQL 13. io.Manager now requires PostgreSQL 14 or later.
New Features
Added support for Node.js 24 LTS. io.Manager now requires Node.js 20 LTS, 22 LTS, or 24 LTS.
Added the following properties to the
auth_basictop-level key of the optionalConfigobject for initializing the io.Manager Server:
Property Type Description sessionLifetimenumberInterval in seconds at which the session will expire and the user will be logged out of the io.Manager Admin UI. Valid only if useSessionCookieis set totrueand the CORS options are configured properly via thecorsproperty. Defaults to3600.useSessionCookiebooleanIf true(default), io.Manager will use a signed JWT stored in a session cookie to manage the Admin UI user sessions. Set tofalseto disable session cookies. If session cookies are enabled, it's required to specify CORS options via thecorsproperty.The following example demonstrates how to increase the Admin UI user session to two hours when using Basic authentication:
import { start } from "@interopio/manager"; const config = { // Enabling Basic authentication. auth_method: "basic", // Additional settings for Basic authentication. auth_basic: { predefinedUsers: ["admin:admin"], // Configuring the user session length for the Admin UI. sessionLifetime: 7200 }, // It's required to specify CORS options when session cookies are enabled. cors: { credentials: true, origin: "http://localhost:3000" } }; const server = await start(config);You can also use the following environment variables:
Environment Variable Description API_AUTH_METHOD_BASIC_SESSION_LIFETIMEInterval in seconds at which the session will expire and the user will be logged out of the io.Manager Admin UI. Valid only if API_AUTH_METHOD_BASIC_USE_SESSION_COOKIEis set totrueand the CORS options are configured properly via theAPI_CORS_OPTIONSenvironment variable. Defaults to3600.API_AUTH_METHOD_BASIC_USE_SESSION_COOKIEIf true(default), io.Manager will use a signed JWT stored in a session cookie to manage the Admin UI user sessions. Set tofalseto disable session cookies. If session cookies are enabled, it's required to specify CORS options via theAPI_CORS_OPTIONSenvironment variable.The following example demonstrates how to increase the Admin UI user session to two hours when using Basic authentication:
API_AUTH_METHOD=basic API_AUTH_METHOD_BASIC_USERS=["admin:admin"] # Configuring the user session length for the Admin UI. API_AUTH_METHOD_BASIC_SESSION_LIFETIME=7200 # It's required to specify CORS options when session cookies are enabled. API_CORS_OPTIONS={"credentials": true, "origin": "http://localhost:3000"}
- Added a
sessionstop-level key to the optionalConfigobject for initializing the io.Manager Server. Use this property to provide configuration for the io.Connect platform sessions. Thesessionsobject has the following properties:
Property Type Description inactiveSessionTimeoutInSecondsnumberInterval in seconds after which an io.Connect platform client session is considered inactive. Sessions are considered active if the connected platform has fetched data within the specified timeout. Must be set to the same value as the "fetchInterval"property of the"server"object in the io.Connect Desktop platform configuration, or thefetchIntervalproperty of themanagerobject in the io.Connect Browser platform configuration respectively. Defaults to30.The following example demonstrates how to configure the inactive session timeout:
import { start } from "@interopio/manager"; const config = { // Configuration for the io.Connect platform sessions. sessions: { // You must specify the same value for the `fetchInterval` property // in the platform configuration for connecting to io.Manager. inactiveSessionTimeoutInSeconds: 90 } }; const server = await start(config);You can also use the following environment variable:
Environment Variable Description API_SESSIONS_INACTIVE_SESSION_TIMEOUTInterval in seconds after which an io.Connect platform client session is considered inactive. Sessions are considered active if the connected platform has fetched data within the specified timeout. Must be set to the same value as the "fetchInterval"property of the"server"object in the io.Connect Desktop platform configuration, or thefetchIntervalproperty of themanagerobject in the io.Connect Browser platform configuration respectively. Defaults to30.
- New REST API endpoints have been added:
New Endpoint Description GET /commands/descriptions/allRetrieves all supported commands across all io.Connect platform versions. The response is in the form of an array of JSON objects. Each object of the resulting array describes a unique supported command and contains information about the command type, the command description, version-specific command parameter examples, and a list of the io.Connect platform versions which support the command. Improvements & Bug Fixes
- Fixed inconsistent handling of the
accessListproperty of an app across stores when set tonull.- Fixed a bug where database schema names weren't properly quoted in PostgreSQL making it impossible to use PostgreSQL keywords as schema names.
- Fixed a bug where updates to the
machinetable were failing on Microsoft SQL Server.- Fixed a bug where io.Manager failed to merge configurations when
identifier.versionwas missing the minor or patch segments.Dependency Changes
The following dependencies have been updated:
@nestjs/swaggerfrom version^11.2.0to^11.2.3dotenvfrom version17.0.0to^17.2.1mimefrom version^1.6.0to^4.1.0mongodbfrom version^6.16.0to^7.0.0mssqlfrom version^11.0.1to^12.2.0tediousfrom version^18.6.1to^19.1.3
2.0.0
Release date: 11.07.2025
⚠️ Note that the following io.Manager NPM packages will now be published in the public NPM registry:
@interopio/manageras of version2.0.0;@interopio/manager-admin-uias of version3.0.0;Previous versions of the packages will still be available in the private JFROG registry.
Breaking Changes
ℹ️ For more details on the breaking changes and the required migration steps, see also the Upgrade section.
⚠️ Note that as of version 2.0.0, io.Manager requires a license key to operate. To acquire a license key, contact us at
sales@interop.io. Existing customers should contact their Client Success representative to obtain a license key.ℹ️ For more details on licensing, see the Requirements > Licensing section.
- Added a required
licenseKeytop-level property in the configuration object for initializing the io.Manager Server. Use this property to supply your io.Manager license key:import { start } from "@interopio/manager"; const config = { // It's now required to provide a valid license key for io.Manager to operate. licenseKey: "my-license-key" }; const server = await start(config);You can also use the
API_LICENSE_KEYenvironment variable:API_LICENSE_KEY=my-license-key
- Dropped Node.js 18 support. io.Manager now requires Node.js 20 LTS or 22 LTS.
- The default value for
skipProcessExitOnStopis changed totrue. If you wantprocess.exit()to be called whenserver.stop()is called or when the server fails to start, setskipProcessExitOnStoptofalse.- Removed the
storeproperty of theServerinterface.- Removed the
UserStore,Store, andBLOBStoreinterfaces.- TypeScript types:
- The
AuditService.getAll()method now returnsAuditLogDataResultinstead ofDataResult<AuditLog>.- When implementing
CustomAuthenticator, you now have to import the following types from@interopio/managerinstead of@interopio/manager-api:
TokenUser- When implementing
AuditService, you now have to import the following types from@interopio/managerinstead of@interopio/manager-api:
AuditLogAuditLogDataResultCleanAuditLogRequestDataRequestUser- When implementing
GroupsService, you now have to import the following types from@interopio/managerinstead of@interopio/manager-api:
DataRequestGroupGroupDataResultGroupsFeaturesUser- The types
AuditLogEntityTypeandAuditLogOperationhave been converted from TypeScript Union types to TypeScript Enums.- Removed the previously deprecated
status_endpointtop-level configuration property.- The
GET /dbendpoint now always returns a500status code regardless of the configured database. Previously, this only worked for MongoDB and returned database statistics specific to MongoDB.- Removed
false,"none", and"sentry"as values for themonitoringproperty. Use{ type: "none" }or{ type: "sentry" }instead.- Removed the
tracesSampleRateproperty from the Sentry monitoring configuration. UsesentryOptions.tracesSampleRateinstead.- Removed the
dsnproperty from the Sentry monitoring configuration. UsesentryOptions.dsninstead.- Tracing via the Sentry SDK is no longer supported. The recommended way to send traces to Sentry is by using OpenTelemetry traces. See also the OpenTelemetry with Sentry example on GitHub.
- Removed
["admin"]as a default value for theAPI_AUTH_EXCLUSIVE_USERSenvironment variable. This change doesn't affect users who don't use environment variables for configuring io.Manager as the default value was valid only for theAPI_AUTH_EXCLUSIVE_USERSenvironment variable.- Due to a change in the FDC3 specification, the
nameanddefinition.nameapp properties won't be checked for consistency for FDC3 app definitions. Thenameanddefinition.appIdproperties will still be checked. For more details, see the FDC3 Standard 2.1.- When using environment variable configuration with
.envfiles, values from the.envfiles will override the process environment variables. This means that if an environment variable is both defined in the.envfile and passed to the process, the value from the.envfile will be used.New Features
- Added OpenAPI 3.0.0 support via Swagger UI.
- Added a
traceContextdatabase column to thecommandstable (for PostgreSQL and Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must create the
traceContextcolumn manually by running the following scripts.For PostgreSQL:
ALTER TABLE commands ADD COLUMN IF NOT EXISTS "traceContext" JSON;For Microsoft SQL Server:
IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[commands]') AND name = 'traceContext' ) ALTER TABLE commands ADD traceContext NVARCHAR(MAX);
- Changed the type of the
commandParamsdatabase column of thecommandstable toJSON(for PostgreSQL only).⚠️ Note that users who don't use automatic schema migration must change the type of the
commandParamscolumn manually by running the following script:ALTER TABLE commands ALTER COLUMN "commandParams" TYPE JSON USING "commandParams"::json;
- Changed the precision of the
weightdatabase column in theglue42SystemConfigtable (for PostgreSQL and Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must change the precision of the
weightcolumn manually by running the following scripts.For PostgreSQL:
ALTER TABLE "glue42SystemConfig" ALTER COLUMN weight TYPE numeric(8, 6) USING weight::numeric(8, 6);For Microsoft SQL Server:
ALTER TABLE glue42SystemConfig ALTER COLUMN weight decimal(8, 6);
- Changed the type of the
definitiondatabase column of thelayoutstable toJSON(for PostgreSQL and Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must change the type of the
definitioncolumn manually by running the following scripts.For PostgreSQL:
ALTER TABLE layouts ALTER COLUMN definition TYPE JSON USING definition::json;For Microsoft SQL Server:
ALTER TABLE layouts ALTER COLUMN definition NVARCHAR(max) NOT NULL;
- Changed the type of the
commentdatabase column of thecrashestable toNVARCHAR(max)(for Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must change the type of the
commentcolumn manually by running the following script:ALTER TABLE crashes ALTER COLUMN comment NVARCHAR(max);
- Changed the types of the
comment,descriptionandattachmentdatabase columns of thefeedbacktable toNVARCHAR(max)(for Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must change the type of the columns manually by running the following script:
ALTER TABLE feedback ALTER COLUMN comment NVARCHAR(max); ALTER TABLE feedback ALTER COLUMN description NVARCHAR(max) NOT NULL; ALTER TABLE feedback ALTER COLUMN attachment NVARCHAR(max) NOT NULL;
- Added an
auth_timeouttop-level key in the configuration object for initializing the io.Manager Server, which accepts a number as a value and defaults to120000. Use this property to specify an interval in milliseconds to wait for the authentication process request to complete before rejecting it. This setting is useful when you have implemented a custom authentication mechanism:import { start } from "@interopio/manager"; import { MyAuthenticator } from "./MyAuthenticator"; const config = { auth_method: "custom", auth_custom: new MyAuthenticator(), auth_timeout: 60000 }; const server = await start(config);You can also use the
API_AUTH_TIMEOUTenvironment variable:API_AUTH_TIMEOUT=60000
Added a
corstop-level key in the configuration object for initializing the io.Manager Server. The value will be passed to thecorsmiddleware. For more details, see the Configuration Options section in thecorspackage documentation.Added an
interceptProcessSignalstop-level key in the configuration object for initializing the io.Manager Server. If set totrue, io.Manager will listen for the following signals:"SIGINT","SIGTERM","SIGHUP","SIGBREAK","SIGQUIT". Defaults tofalse. You can also use theAPI_INTERCEPT_PROCESS_SIGNALSenvironment variable.Added new properties to the
purgetop-level key in the configuration object for initializing the io.Manager Server. Use these properties to configure the data purging functionality of io.Manager:
Property Type Description purgeCommandsAfterDaysnumberNumber of days after which an executed command and the respective command result become eligible for purging. Set to -1to disable purging of commands and command results. Defaults to90.scheduledTaskIntervalnumberInterval in milliseconds at which to run the periodic data purging operation. Defaults to 86400000(1 day).You can also use the following environment variables:
Environment Variable Description API_PURGE_COMMANDS_AFTER_DAYSNumber of days after which an executed command and the respective command result become eligible for purging. Set to -1to disable purging of commands and command results. Defaults to90.API_PURGE_SCHEDULED_TASK_INTERVALInterval in milliseconds at which to run the periodic data purging operation. Defaults to 86400000(1 day).
Added a
sentryClientproperty to theSentryMonitoringConfigobject. Use to provide an already initialized Sentry client. Useful if you want to initialize Sentry manually before starting io.Manager. For more details, see the Sentry for Node.js guide in the official Sentry documentation.Added a
sentryOptionsproperty toSentryMonitoringConfigobject. Passed to theSentry.init()method. Ignored when a Sentry client is provided via thesentryClientproperty. For more details, see the Configuration Options section in the official Sentry documentation.Added a
customPropagatorproperty toOtelTracingConfigobject. Use to provide a custom OpenTelemetry propagator.Added a
customContextManagerproperty toOtelTracingConfigobject. Use to provide a custom OpenTelemetry context manager.Added a new
API_LOG_LEVELenvironment variable. Use to set thelog4jslog level when using environment variable configuration. Defaults toinfo.Improvements & Bug Fixes
- Added a new
CustomAuthUnauthorizedErrorexport. Used in custom authenticator implementations.- Added a new
OtelConfigexport. Exports the existing OpenTelemetry configuration type.- The
nametop-level configuration property is now optional. If not provided, the server will use the default value of"local".- The
porttop-level configuration property is now optional. If not provided, the server will use the default value of4356.Deprecated Endpoints
The following REST API endpoints have been deprecated:
Deprecated Endpoint New Endpoint GET /dbUse GET /db-connectivityinstead.GET /server/infoUse GET /v2/server/infoinstead.Dependency Changes
The following new dependencies have been added to the package:
@nestjs/commonversion^11.1.0@nestjs/coreversion^11.1.0@nestjs/platform-expressversion^11.1.0@nestjs/swaggerversion^11.2.0@opentelemetry/instrumentation-nestjs-coreversion^0.46.0mimeversion^1.6.0rxjsversion^7.8.2tediousversion^18.6.1The following dependencies have been removed from the package:
@interopio/manager-api@sentry/tracing@types/bcryptjs@types/cookie-parser@types/lodash@types/multer@types/shortidajvcross-envThe following dependencies were updated:
@interopio/otelfrom version^0.0.14to^0.0.67@interopio/schemasfrom version^9.2.0to^9.7.0@okta/jwt-verifierfrom version^3.1.0to^4.0.1@opentelemetry/api-logsfrom version^0.54.0to^0.200.0@opentelemetry/exporter-logs-otlp-httpfrom version^0.54.0to^0.200.0@opentelemetry/exporter-metrics-otlp-httpfrom version^0.54.0to^0.200.0@opentelemetry/exporter-trace-otlp-httpfrom version^0.54.0to^0.200.0@opentelemetry/instrumentationfrom version^0.54.0to^0.200.0@opentelemetry/instrumentation-expressfrom version^0.43.0to^0.49.0@opentelemetry/instrumentation-httpfrom version^0.54.0to^0.200.0@opentelemetry/instrumentation-knexfrom version^0.40.0to^0.45.0@opentelemetry/instrumentation-mongodbfrom version^0.47.0to^0.53.0@opentelemetry/instrumentation-undicifrom version^0.6.0to^0.11.0@opentelemetry/resourcesfrom version^1.27.0to^2.0.0@opentelemetry/sdk-logsfrom version^0.54.0to^0.200.0@opentelemetry/sdk-metricsfrom version^1.27.0to^2.0.0@opentelemetry/sdk-trace-basefrom version^1.27.0to^2.0.0@opentelemetry/sdk-trace-nodefrom version^1.27.0to^2.0.0@opentelemetry/semantic-conventionsfrom version^1.27.0to^1.33.0@sentry/nodefrom version^7.13.0to^9.18.0bcryptjsfrom version^2.4.3to^3.0.2cookie-parserfrom version^1.4.6to^1.4.7dotenvfrom version^16.4.5to17.0.0expressfrom version^4.17.1to^5.1.0express-oauth2-jwt-bearerfrom version^1.4.1to^1.6.1jsonwebtokenfrom version^9.0.0to^9.0.2knexfrom version^2.4.1to^3.1.0mongodbfrom version^4.11.0to^6.16.0mssqlfrom version^9.1.1to^11.0.1multerfrom versionnpm:@interopio/multer@^1.4.5-lts.1tonpm:@interopio/multer@^2.0.0pgfrom version^8.7.3to^8.16.0reflect-metadatafrom version^0.1.13to^0.2.2semverfrom version^7.5.2to^7.7.2shortidfrom version^2.2.8to^2.2.17
1.0
1.8.2
Release date: 27.03.2025
Improvements & Bug Fixes
- Removed the "user" field from the
serverx-tokenheader passed from io.Connect to io.Manager.
1.8.1
Release date: 26.02.2025
New Features
- It's now possible to define custom status messages for health checks:
- Added a
healthCheckStatusoptional string property to theHealthEndpointsConfigobject. The string will be passed as a value to the"status"field in the health check response. You can also use theAPI_HEALTH_ENDPOINTS_CUSTOM_HEALTHCHECK_STATUSenvironment variable.- Added a
databaseHealthCheckStatusoptional string property to theHealthEndpointsConfigobject. The string that the database connectivity health check will return as a successful response. You can also use theAPI_HEALTH_ENDPOINTS_CUSTOM_DB_CONNECTIVITY_STATUSenvironment variable.
1.8.0
Release date: 24.02.2025
New Features
- Implemented additional health check endpoints on custom routes:
- Added a
customHealthCheckRouteoptional string property to theHealthEndpointsConfigobject. If present, an additional health check endpoint will be available on the specified route. You can also use theAPI_HEALTH_ENDPOINTS_CUSTOM_HEALTHCHECK_ROUTEenvironment variable.- Added a
customDatabaseHealthCheckRouteoptional string property to theHealthEndpointsConfigobject. If present, an additional database health check endpoint will be available on the specified route. You can also use theAPI_HEALTH_ENDPOINTS_CUSTOM_DB_CONNECTIVITY_HEALTHCHECK_ROUTEenvironment variable.
1.7.4
Release date: 20.02.2025
Improvements & Bug Fixes
- Relaxed the
DataRequestJSON filter validation to safely allow using arbitrary JSON fields.
1.7.3
Release date: 20.11.2024
Improvements & Bug Fixes
- Fixed a bug where sometimes the io.Manager Server would fail to load environment variables from a file.
1.7.2
Release date: 19.11.2024
Improvements & Bug Fixes
- Added consistency validation for apps:
nameanddefinition.namemust be the same;nameanddefinition.appId(if present) must be the same;- Added consistency validation for Layouts:
nameanddefinition.namemust be the same;typeanddefinition.typemust be the same;
1.7.1
Release date: 07.11.2024
New Features
- Exposed
appsV2andlayoutsV2via theServerinterface for custom scripts.Improvements & Bug Fixes
- Fixed a bug where some PostgreSQL queries wouldn't use the correct schema.
1.7.0
Release date: 01.11.2024
New Features
- Added OpenTelemetry support.
- Added new environment variable
API_MONITORING_SENTRY_DSN- custom Sentry DSN to use when using monitoring via Sentry.- Added new environment variable
API_AUTH_AUTH0_ISSUER_BASE_URLfor Auth0 authentication - base URL for the Auth0 issuer.- Added database connectivity health check as well as Docker health checks for the io.Manager Server and Admin UI Docker images.
- Added a
purgeAtStartupEnabledoptional Boolean property to thePurgeConfigobject. If set totrue(default), will run the purge task at startup of the io.Manager Server. You can also use theAPI_PURGE_AT_STARTUP_ENABLEDenvironment variable to configure the purge behavior.- Added database column
othersto thelast_updatedtable (for PostgreSQL and Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must create the
otherscolumn manually by running the following scripts.For PostgreSQL:
ALTER TABLE last_updated ADD COLUMN IF NOT EXISTS others JSON NULL;For Microsoft SQL Server:
IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[last_updated]') AND name = 'others' ) ALTER TABLE last_updated ADD others NVARCHAR(MAX);
1.6.4
Release date: 11.09.2024
Improvements & Bug Fixes
- Fixed a bug where io.Manager would fail to save a crash dump generated by io.Connect Desktop.
1.6.3
Release date: 10.09.2024
Improvements & Bug Fixes
- Fixed a bug where invoking controllers directly via the
RestServerclass would throw an error.
1.6.2
Release date: 05.09.2024
Improvements & Bug Fixes
- Moved
dotenvpackage from"devDependencies"to"dependencies"to fix a bug introduced in v1.6.0.
1.6.1
Release date: 04.09.2024
Improvements & Bug Fixes
- Fixed a bug where the total record count wasn't calculated correctly for data requests to PostgreSQL and Microsoft SQL Server.
1.6.0
Release date: 29.08.2024
New Features
- Implemented automatic failover when using PostgreSQL databases with io.Manager. To specify multiple PostgreSQL hosts, use the
hostsproperty of thestoreobject for configuring the connection to a PostgreSQL database. Thehostsproperty accepts an array of objects describing PostgreSQL database hosts that will be tried in the order they are provided.The following example demonstrates configuring io.Manager Server to use multiple PostgreSQL hosts:
import { start } from "@interopio/manager"; // Configuration for the io.Manager Server. const config = { name: "my-server", port: 4242, token: { secret: "my-secret" }, // Configuration for connecting to a PostgreSQL database. store: { type: "postgresql", // Specifying multiple PostgreSQL hosts to which to connect. hosts: [ { connection: "postgresql://my_user:password@localhost:5432", dbName: "my_db", schemaName: "my_schema" }, { connection: "postgresql://my_user:password@localhost:5433", dbName: "my_db", schemaName: "my_schema", // io.Manager won't attempt to execute write operations on this host. isReadOnly: true } ] } }; // Initializing the io.Manager Server. const server = await start(config);Improvements & Bug Fixes
- Added database column
browserto themachinestable (for PostgreSQL and Microsoft SQL Server only).⚠️ Note that users who don't use automatic schema migration must create the
browsercolumn manually by running the following scripts.For PostgreSQL:
ALTER TABLE machines ADD COLUMN IF NOT EXISTS browser JSON NULL;For Microsoft SQL Server:
IF NOT EXISTS ( SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'[dbo].[machines]') AND name = 'browser' ) ALTER TABLE machines ADD browser NVARCHAR(MAX);
- Fixed a bug that would prevent MongoDB users from seeing feedback in the feedback list in the io.Manager Admin UI.
- Layouts can now be filtered by the
idfield using the Admin API.
1.5.0
Release date: 16.08.2024
New Features
- New REST API endpoints have been added:
New Endpoint Description GET /v2/server/infoReturns information about the io.Manager Server, such as server version and available capabilities. POST /v2/apps/addCreates a new app definition or returns status code 400if an app definition with the samenameproperty already exists. Returns the created app definition.POST /v2/apps/add-or-updateCreates a new app definition or updates an existing one if an app definition with the same nameproperty already exists. Returns the created or updated app definition.POST /v2/apps/updateUpdates an app definition or returns status code 404if an app definition with the specifiednameproperty isn't found. Returns the updated app definition.POST /v2/layouts/addCreates a new Layout definition or returns status code 400if a Layout definition with the same combination ofname,typeandownerproperties already exists. Returns the created Layout definition.POST /v2/layouts/add-or-updateCreates a new Layout definition or updates an existing one if a Layout definition with the same idproperty (or the same combination ofname,typeandownerproperties ifidisn't provided) already exists. Returns the created or updated Layout definition.POST /v2/layouts/updateUpdates a Layout definition or returns status code 404if a Layout definition with the specifiedidproperty (or the specified combination ofname,typeandownerproperties ifidisn't provided) isn't found. Returns the updated Layout definition.Deprecated Endpoints
The following REST API endpoints have been deprecated:
Deprecated Endpoint New Endpoint POST /appsUse POST /v2/apps/add-or-updateinstead.POST /apps/:nameUse POST /v2/apps/updateinstead.POST /layoutsUse POST /v2/layouts/add-or-updateinstead.POST /users/:name/layoutsUse POST /v2/layouts/addinstead.
1.4.0
Release date: 15.05.2024
New Features
- Support for Okta authentication.
- Implemented
"empty"DataRequestfilter type for all filter types where applicable.Improvements & Bug Fixes
- Added
inRangefilters support for MongoDB.- Fixed preferences upsert.
1.3.0
Release date: 26.04.2024
New Features
- DB purge operation now happens at startup.
- Exposed extra Microsoft SQL Server options.
Improvements & Bug Fixes
- Fixed inconsistent group resolution between apps and Layouts in io.Manager.
- Fixed broken last updated timestamps in io.Manager leading to unnecessary database requests and hashing operations when configured with PostgreSQL or Microsoft SQL Server.
- Fixed summary endpoint on Microsoft SQL Server and PostgreSQL.
- DB purge interval is stopped when
server.stop()is called.- Remove server-x token groups usage in sessions service.
1.2.0
Release date: 22.03.2024
New Features
- Added a configurable purge job for purging old audit logs, feedback and crashes in order to reduce database usage.
- Added
API_STORE_POSTGRESQL_NATIVE_PG_DRIVERandAPI_STORE_MSSQL_DOMAINenvironment variables.Improvements & Bug Fixes
- Implemented ORFilters and excludeFields for PostgreSQL and Microsoft SQL Server.
- User groups defined in database are considered when using custom auth provider and the data store.
- Rebuilt the Data Request functionality for PostgreSQL and Microsoft SQL Server to use SQL parameters. Fixed various related bugs.
- Added migration for missing constraints in
layoutsandprefstables in PostgreSQL and Microsoft SQL Server.
1.1.1
Release date: 06.03.2024
Improvements & Bug Fixes
- When a user saves a shared Layout, a new private copy of that Layout is created. Previously, the shared Layout was transferred to the user that had saved it.
1.1.0
Release date: 24.02.2024
New Features
- Added support for
pg-nativedriver.⚠️ Note that
pg-nativeisn't a dependency of the@interopio/managerpackage and you must install it separately in your project.Improvements & Bug Fixes
- Microsoft SQL Server support: fixed a bug where the
accessListcolumn of theappstable wasn't written if empty.- Updated dependencies.
1.0.0
Release date: 17.01.2024
Breaking Changes
- Users can now be compared in a case-insensitive way. Added new a configuration property
username_case_sensitiveand a new environment variableAPI_USERNAME_CASE_SENSITIVEthat can be used to switch between case-sensitive and case-insensitive modes. Defaults to case-insensitive.- Removed status endpoint, because the
express-status-monitorpackage is deprecated.Improvements & Bug Fixes
- Updated dependencies.
0.1
0.20.1
Release date: 20.10.2023
Improvements & Bug Fixes
- Updated dependencies.
0.20.0
Release date: 09.10.2023
New Features
- Added option for controlling audit logs.
Improvements & Bug Fixes
- Stopped recreating controllers on every request.
- Disabled auditing for opening sessions open and creating users.
0.19.2
Release date: 05.09.2023
Improvements & Bug Fixes
- Fixed updating a Layout without a Layout ID.
0.19.1
Release date: 14.07.2023
Improvements & Bug Fixes
- Moved several types from development dependencies to dependencies.
0.19.0
Release date: 14.07.2023
New Features
- Added support for Microsoft SQL Server databases.
0.18.0
Release date: 15.06.2023
New Features
- Added explicit Layouts support for PostgreSQL.
- Auth0 authentication now uses permissions.
Improvements & Bug Fixes
- Fixed rejecting hello request from io.Connect Browser.
0.17.1
Release date: 30.05.2023
Improvements & Bug Fixes
- Moved some of the libraries into the codebase for better control over the dependencies.
0.17.0
Release date: 22.05.2023
New Features
- Exposed APIs (e.g., for users, apps, Layouts and more) attached to the initialized
serverobject.
0.16.0
Release date: 19.05.2023
New Features
- Added ability to set explicit Layouts for users.
0.15.2
Release date: 18.05.2023
Improvements & Bug Fixes
- Optimized fetching of user Layouts.
0.15.1
Release date: 11.05.2023
Improvements & Bug Fixes
- Exposed all options for Auth0 configuration.
0.15.0
Release date: 11.05.2023
New Features
- Restored Auth0 authentication support.
0.14.0
Release date: 11.04.2023
New Features
- Added an extra pool setting for PostgreSQL connections.
0.13.0
Release date: 31.03.2023
Improvements & Bug Fixes
- Updated to latest
@interopio/schemas.
0.12.1
Release date: 16.03.2023
Improvements & Bug Fixes
- Updated dependencies.
0.12.0
Release date: 26.01.2023
New Features
- Allow a single default Layout entry in the database.
Improvements & Bug Fixes
- Prevented users from overwriting common Layouts.
0.11.0
Release date: 25.11.2022
New Features
- Added HTTPS support.
0.10.0
Release date: 28.10.2022
New Features
- Added support for PostgreSQL databases.
0.9.11
Release date: 12.10.2022
Improvements & Bug Fixes
- Added option to disable
express-status-monitor.
0.9.10
Release date: 10.10.2022
Improvements & Bug Fixes
- Fixed always converting the port in the server configuration to a number. Now, if a string is passed, it's treated as a path that might be a named pipe.
0.9.9
Release date: 21.09.2022
New Features
- Added a
/statusendpoint usingexpress-status-monitor.- Added a
/dbendpoint for database info.
0.9.8
Release date: 19.09.2022
Improvements & Bug Fixes
0.9.7
Release date: 19.09.2022
Improvements & Bug Fixes
- Removed sort memory limit.
0.9.6
Release date: 19.09.2022
Improvements & Bug Fixes
- Improved the shutdown process.
0.9.5
Release date: 07.09.2022
Improvements & Bug Fixes
- Improved Sentry monitoring routes.
0.9.4
Release date: 24.08.2022
New Features
- Added Sentry monitoring.
0.8.4
Release date: 07.06.2022
Improvements & Bug Fixes
- Updated to latest
@interopio/server-api.
0.8.3
Release date: 07.06.2022
Improvements & Bug Fixes
- Hashed passwords (only used in Basic authentication).
- Updated dependencies.
0.8.2
Release date: 23.03.2022
Improvements & Bug Fixes
- Handled schema validator errors.
0.8.1
Release date: 23.03.2022
Improvements & Bug Fixes
- Fixed schema path.
0.8.0
Release date: 22.03.2022
New Features
- Added a
/schemaendpoint.
0.7.0
Release date: 21.03.2022
New Features
- Added a flow for Basic authentication.
- Added a
/whoamiendpoint.
0.6.0
Release date: 17.03.2022
New Features
- Added a default route.
- Added a stop route that is registered only if an environment variable is present in the configuration.
0.5.0
Release date: 13.03.2022
New Features
- Added a
/capabilitiesendpoint for exposing the features of Groups.
0.4.1
Release date: 13.03.2022
Improvements & Bug Fixes
- Included the tests as pre-publish step.
0.4.0
Release date: 13.03.2022
New Features
- Added the option to provide a custom Groups service.