diff --git a/src/slack/monitor/auth.test.ts b/src/slack/monitor/auth.test.ts new file mode 100644 index 00000000000..ca9ac20254d --- /dev/null +++ b/src/slack/monitor/auth.test.ts @@ -0,0 +1,40 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; +import type { SlackMonitorContext } from "./context.js"; + +const readChannelAllowFromStoreMock = vi.hoisted(() => vi.fn()); + +vi.mock("../../pairing/pairing-store.js", () => ({ + readChannelAllowFromStore: (...args: unknown[]) => readChannelAllowFromStoreMock(...args), +})); + +import { resolveSlackEffectiveAllowFrom } from "./auth.js"; + +function makeSlackCtx(allowFrom: string[]): SlackMonitorContext { + return { + allowFrom, + } as unknown as SlackMonitorContext; +} + +describe("resolveSlackEffectiveAllowFrom", () => { + beforeEach(() => { + readChannelAllowFromStoreMock.mockReset(); + }); + + it("falls back to channel config allowFrom when pairing store throws", async () => { + readChannelAllowFromStoreMock.mockRejectedValueOnce(new Error("boom")); + + const effective = await resolveSlackEffectiveAllowFrom(makeSlackCtx(["u1"])); + + expect(effective.allowFrom).toEqual(["u1"]); + expect(effective.allowFromLower).toEqual(["u1"]); + }); + + it("treats malformed non-array pairing-store responses as empty", async () => { + readChannelAllowFromStoreMock.mockReturnValueOnce(undefined); + + const effective = await resolveSlackEffectiveAllowFrom(makeSlackCtx(["u1"])); + + expect(effective.allowFrom).toEqual(["u1"]); + expect(effective.allowFromLower).toEqual(["u1"]); + }); +}); diff --git a/src/slack/monitor/auth.ts b/src/slack/monitor/auth.ts index 421bc084d92..0b5ba9469b4 100644 --- a/src/slack/monitor/auth.ts +++ b/src/slack/monitor/auth.ts @@ -13,13 +13,19 @@ export async function resolveSlackEffectiveAllowFrom( options?: { includePairingStore?: boolean }, ) { const includePairingStore = options?.includePairingStore === true; - const storeAllowFrom = includePairingStore - ? await readStoreAllowFromForDmPolicy({ + let storeAllowFrom: string[] = []; + if (includePairingStore) { + try { + const resolved = await readStoreAllowFromForDmPolicy({ provider: "slack", accountId: ctx.accountId, dmPolicy: ctx.dmPolicy, - }) - : []; + }); + storeAllowFrom = Array.isArray(resolved) ? resolved : []; + } catch { + storeAllowFrom = []; + } + } const allowFrom = normalizeAllowList([...ctx.allowFrom, ...storeAllowFrom]); const allowFromLower = normalizeAllowListLower(allowFrom); return { allowFrom, allowFromLower };