fix(matrix): narrow live allowlist reload reads

This commit is contained in:
Gustavo Madeira Santana
2026-04-19 15:40:16 -04:00
parent be92ee8e70
commit 58c9d4a2b2
3 changed files with 70 additions and 4 deletions

View File

@@ -148,3 +148,28 @@ export function resolveMatrixAccountConfig(params: {
...(rooms ? { rooms } : {}),
};
}
export function resolveMatrixAccountAllowlistConfig(params: {
cfg: CoreConfig;
accountId?: string | null;
}): {
dmAllowFrom?: NonNullable<MatrixConfig["dm"]>["allowFrom"];
groupAllowFrom?: MatrixConfig["groupAllowFrom"];
} {
const accountId = normalizeAccountId(params.accountId);
const base = resolveMatrixBaseConfig(params.cfg);
const accountConfig = findMatrixAccountConfig(params.cfg, accountId);
const accountDm = accountConfig?.dm;
let dmAllowFrom = base.dm?.allowFrom;
if (accountDm && Object.hasOwn(accountDm, "allowFrom")) {
dmAllowFrom = accountDm.allowFrom;
}
let groupAllowFrom = base.groupAllowFrom;
if (accountConfig && Object.hasOwn(accountConfig, "groupAllowFrom")) {
groupAllowFrom = accountConfig.groupAllowFrom;
}
return { dmAllowFrom, groupAllowFrom };
}

View File

@@ -1841,6 +1841,47 @@ describe("matrix monitor handler live allowlist reload", () => {
expect(dispatchReplyFromConfig).toHaveBeenCalledTimes(1);
});
it("uses account-scoped live dm.allowFrom overrides", async () => {
const dispatchReplyFromConfig = createDispatchReplyFromConfig();
const cfg = {
channels: {
matrix: {
dm: { allowFrom: ["@base:example.org"] },
accounts: {
ops: {
dm: { allowFrom: ["@alice:example.org"] },
},
},
},
},
};
const { handler } = createMatrixHandlerTestHarness({
cfg,
accountId: "ops",
dmPolicy: "allowlist",
isDirectMessage: true,
allowFrom: ["@alice:example.org"],
allowFromResolvedEntries: [{ input: "@alice:example.org", id: "@alice:example.org" }],
dispatchReplyFromConfig,
});
await sendLiveAllowlistMessage(handler, {
eventId: "$dm-account-before",
sender: "@alice:example.org",
body: "hello",
});
expect(dispatchReplyFromConfig).toHaveBeenCalledTimes(1);
cfg.channels.matrix.accounts.ops.dm.allowFrom = [];
await sendLiveAllowlistMessage(handler, {
eventId: "$dm-account-after",
sender: "@alice:example.org",
body: "hello again",
});
expect(dispatchReplyFromConfig).toHaveBeenCalledTimes(1);
});
it("keeps startup-resolved display names only while the raw input remains configured", async () => {
const dispatchReplyFromConfig = createDispatchReplyFromConfig();
const cfg = {

View File

@@ -14,7 +14,7 @@ import type {
MatrixStreamingMode,
ReplyToMode,
} from "../../types.js";
import { resolveMatrixAccountConfig } from "../account-config.js";
import { resolveMatrixAccountAllowlistConfig } from "../account-config.js";
import { formatMatrixErrorMessage } from "../errors.js";
import { isMatrixMediaSizeLimitError } from "../media-errors.js";
import {
@@ -706,17 +706,17 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam
};
const storeAllowFrom = isDirectMessage ? await readStoreAllowFrom() : [];
const roomUsers = roomConfig?.users ?? [];
const liveAccountCfg = resolveMatrixAccountConfig({
const liveAccountAllowlists = resolveMatrixAccountAllowlistConfig({
cfg: core.config.loadConfig() as CoreConfig,
accountId,
});
const liveDmAllowFrom = resolveEffectiveMatrixLiveAllowlist({
liveEntries: liveAccountCfg.dm?.allowFrom,
liveEntries: liveAccountAllowlists.dmAllowFrom,
startupResolvedEntries: allowFromResolvedEntries,
fallbackEntries: allowFrom,
});
const liveGroupAllowFrom = resolveEffectiveMatrixLiveAllowlist({
liveEntries: liveAccountCfg.groupAllowFrom,
liveEntries: liveAccountAllowlists.groupAllowFrom,
startupResolvedEntries: groupAllowFromResolvedEntries,
fallbackEntries: groupAllowFrom,
});