From 8a746e047d4047d630231763bb7b491b140bf3e8 Mon Sep 17 00:00:00 2001 From: Gustavo Madeira Santana Date: Wed, 25 Feb 2026 17:45:47 -0500 Subject: [PATCH] matrix-js: scope channels add config by account --- .../matrix-js/src/channel.directory.test.ts | 38 +++++++++++++ extensions/matrix-js/src/channel.ts | 54 ++++++++++++++++--- 2 files changed, 85 insertions(+), 7 deletions(-) diff --git a/extensions/matrix-js/src/channel.directory.test.ts b/extensions/matrix-js/src/channel.directory.test.ts index 16d9b1b12d1..3d24a4fb1ea 100644 --- a/extensions/matrix-js/src/channel.directory.test.ts +++ b/extensions/matrix-js/src/channel.directory.test.ts @@ -132,4 +132,42 @@ describe("matrix directory", () => { }), ).toBe(false); }); + + it("writes matrix-js non-default account credentials under channels.matrix-js.accounts", () => { + const cfg = { + channels: { + "matrix-js": { + homeserver: "https://default.example.org", + accessToken: "default-token", + }, + }, + } as unknown as CoreConfig; + + const updated = matrixPlugin.setup!.applyAccountConfig({ + cfg, + accountId: "ops", + input: { + homeserver: "https://matrix.example.org", + userId: "@ops:example.org", + accessToken: "ops-token", + }, + }) as CoreConfig; + + expect(updated.channels?.["matrix-js"]?.accessToken).toBe("default-token"); + expect(updated.channels?.["matrix-js"]?.accounts?.ops).toMatchObject({ + enabled: true, + homeserver: "https://matrix.example.org", + userId: "@ops:example.org", + accessToken: "ops-token", + }); + }); + + it("rejects useEnv for non-default matrix-js accounts", () => { + const error = matrixPlugin.setup!.validateInput?.({ + cfg: {} as CoreConfig, + accountId: "ops", + input: { useEnv: true }, + }); + expect(error).toBe("MATRIX_* env vars can only be used for the default account."); + }); }); diff --git a/extensions/matrix-js/src/channel.ts b/extensions/matrix-js/src/channel.ts index 61cee32565d..a510856f6c0 100644 --- a/extensions/matrix-js/src/channel.ts +++ b/extensions/matrix-js/src/channel.ts @@ -4,6 +4,7 @@ import { DEFAULT_ACCOUNT_ID, deleteAccountFromConfigSection, formatPairingApproveHint, + migrateBaseNameToDefaultAccount, normalizeAccountId, PAIRING_APPROVED_MESSAGE, resolveAllowlistProviderRuntimeGroupPolicy, @@ -63,6 +64,7 @@ function normalizeMatrixMessagingTarget(raw: string): string | undefined { function buildMatrixConfigUpdate( cfg: CoreConfig, + accountId: string, input: { homeserver?: string; userId?: string; @@ -74,6 +76,34 @@ function buildMatrixConfigUpdate( }, ): CoreConfig { const existing = cfg.channels?.["matrix-js"] ?? {}; + if (accountId !== DEFAULT_ACCOUNT_ID) { + return { + ...cfg, + channels: { + ...cfg.channels, + "matrix-js": { + ...existing, + enabled: true, + accounts: { + ...existing.accounts, + [accountId]: { + ...existing.accounts?.[accountId], + enabled: true, + ...(input.homeserver ? { homeserver: input.homeserver } : {}), + ...(input.userId ? { userId: input.userId } : {}), + ...(input.accessToken ? { accessToken: input.accessToken } : {}), + ...(input.password ? { password: input.password } : {}), + ...(typeof input.register === "boolean" ? { register: input.register } : {}), + ...(input.deviceName ? { deviceName: input.deviceName } : {}), + ...(typeof input.initialSyncLimit === "number" + ? { initialSyncLimit: input.initialSyncLimit } + : {}), + }, + }, + }, + }, + }; + } return { ...cfg, channels: { @@ -320,7 +350,10 @@ export const matrixPlugin: ChannelPlugin = { accountId, name, }), - validateInput: ({ input }) => { + validateInput: ({ accountId, input }) => { + if (input.useEnv && accountId !== DEFAULT_ACCOUNT_ID) { + return "MATRIX_* env vars can only be used for the default account."; + } if (input.useEnv) { return null; } @@ -343,26 +376,33 @@ export const matrixPlugin: ChannelPlugin = { } return null; }, - applyAccountConfig: ({ cfg, input }) => { + applyAccountConfig: ({ cfg, accountId, input }) => { const namedConfig = applyAccountNameToChannelSection({ cfg: cfg as CoreConfig, channelKey: "matrix-js", - accountId: DEFAULT_ACCOUNT_ID, + accountId, name: input.name, }); + const next = + accountId !== DEFAULT_ACCOUNT_ID + ? migrateBaseNameToDefaultAccount({ + cfg: namedConfig, + channelKey: "matrix-js", + }) + : namedConfig; if (input.useEnv) { return { - ...namedConfig, + ...next, channels: { - ...namedConfig.channels, + ...next.channels, "matrix-js": { - ...namedConfig.channels?.["matrix-js"], + ...next.channels?.["matrix-js"], enabled: true, }, }, } as CoreConfig; } - return buildMatrixConfigUpdate(namedConfig as CoreConfig, { + return buildMatrixConfigUpdate(next as CoreConfig, accountId, { homeserver: input.homeserver?.trim(), userId: input.userId?.trim(), accessToken: input.accessToken?.trim(),