From 37aaca0d4e309ddf7341c009072c9395f552299d Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 15 Feb 2026 12:56:06 +0000 Subject: [PATCH] refactor(discord): share component DM auth context --- src/discord/monitor/agent-components.ts | 66 ++++++++++++++----------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/src/discord/monitor/agent-components.ts b/src/discord/monitor/agent-components.ts index f3a04db91d..898b0d419d 100644 --- a/src/discord/monitor/agent-components.ts +++ b/src/discord/monitor/agent-components.ts @@ -35,6 +35,10 @@ type DiscordUser = Parameters[0]; type AgentComponentInteraction = ButtonInteraction | StringSelectMenuInteraction; +type ComponentInteractionContext = NonNullable< + Awaited> +>; + type DiscordChannelContext = { channelName: string | undefined; channelSlug: string; @@ -349,6 +353,34 @@ async function ensureDmComponentAuthorized(params: { return false; } +async function resolveInteractionContextWithDmAuth(params: { + ctx: AgentComponentContext; + interaction: AgentComponentInteraction; + label: string; + componentLabel: string; +}): Promise { + const interactionCtx = await resolveComponentInteractionContext({ + interaction: params.interaction, + label: params.label, + }); + if (!interactionCtx) { + return null; + } + if (interactionCtx.isDirectMessage) { + const authorized = await ensureDmComponentAuthorized({ + ctx: params.ctx, + interaction: params.interaction, + user: interactionCtx.user, + componentLabel: params.componentLabel, + replyOpts: interactionCtx.replyOpts, + }); + if (!authorized) { + return null; + } + } + return interactionCtx; +} + export class AgentComponentButton extends Button { label = AGENT_BUTTON_KEY; customId = `${AGENT_BUTTON_KEY}:seed=1`; @@ -378,9 +410,11 @@ export class AgentComponentButton extends Button { const { componentId } = parsed; - const interactionCtx = await resolveComponentInteractionContext({ + const interactionCtx = await resolveInteractionContextWithDmAuth({ + ctx: this.ctx, interaction, label: "agent button", + componentLabel: "button", }); if (!interactionCtx) { return; @@ -396,19 +430,6 @@ export class AgentComponentButton extends Button { memberRoleIds, } = interactionCtx; - if (isDirectMessage) { - const authorized = await ensureDmComponentAuthorized({ - ctx: this.ctx, - interaction, - user, - componentLabel: "button", - replyOpts, - }); - if (!authorized) { - return; - } - } - // P2 FIX: Check user allowlist before processing component interaction // This prevents unauthorized users from injecting system events const guildInfo = resolveDiscordGuildEntry({ @@ -496,9 +517,11 @@ export class AgentSelectMenu extends StringSelectMenu { const { componentId } = parsed; - const interactionCtx = await resolveComponentInteractionContext({ + const interactionCtx = await resolveInteractionContextWithDmAuth({ + ctx: this.ctx, interaction, label: "agent select", + componentLabel: "select menu", }); if (!interactionCtx) { return; @@ -514,19 +537,6 @@ export class AgentSelectMenu extends StringSelectMenu { memberRoleIds, } = interactionCtx; - if (isDirectMessage) { - const authorized = await ensureDmComponentAuthorized({ - ctx: this.ctx, - interaction, - user, - componentLabel: "select menu", - replyOpts, - }); - if (!authorized) { - return; - } - } - // Check user allowlist before processing component interaction const guildInfo = resolveDiscordGuildEntry({ guild: interaction.guild ?? undefined,