Skip to content

Commit ac3db09

Browse files
committed
refactor(discord): share component allowlist check
1 parent b2c4269 commit ac3db09

1 file changed

Lines changed: 45 additions & 23 deletions

File tree

src/discord/monitor/agent-components.ts

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,40 @@ async function ensureGuildComponentMemberAllowed(params: {
205205
return false;
206206
}
207207

208+
async function ensureAgentComponentInteractionAllowed(params: {
209+
ctx: AgentComponentContext;
210+
interaction: AgentComponentInteraction;
211+
channelId: string;
212+
rawGuildId: string | undefined;
213+
memberRoleIds: string[];
214+
user: DiscordUser;
215+
replyOpts: { ephemeral?: boolean };
216+
componentLabel: string;
217+
unauthorizedReply: string;
218+
}): Promise<{ parentId: string | undefined } | null> {
219+
const guildInfo = resolveDiscordGuildEntry({
220+
guild: params.interaction.guild ?? undefined,
221+
guildEntries: params.ctx.guildEntries,
222+
});
223+
const channelCtx = resolveDiscordChannelContext(params.interaction);
224+
const memberAllowed = await ensureGuildComponentMemberAllowed({
225+
interaction: params.interaction,
226+
guildInfo,
227+
channelId: params.channelId,
228+
rawGuildId: params.rawGuildId,
229+
channelCtx,
230+
memberRoleIds: params.memberRoleIds,
231+
user: params.user,
232+
replyOpts: params.replyOpts,
233+
componentLabel: params.componentLabel,
234+
unauthorizedReply: params.unauthorizedReply,
235+
});
236+
if (!memberAllowed) {
237+
return null;
238+
}
239+
return { parentId: channelCtx.parentId };
240+
}
241+
208242
export type AgentComponentContext = {
209243
cfg: OpenClawConfig;
210244
accountId: string;
@@ -430,29 +464,23 @@ export class AgentComponentButton extends Button {
430464
memberRoleIds,
431465
} = interactionCtx;
432466

433-
// P2 FIX: Check user allowlist before processing component interaction
434-
// This prevents unauthorized users from injecting system events
435-
const guildInfo = resolveDiscordGuildEntry({
436-
guild: interaction.guild ?? undefined,
437-
guildEntries: this.ctx.guildEntries,
438-
});
439-
const channelCtx = resolveDiscordChannelContext(interaction);
440-
const { parentId } = channelCtx;
441-
const memberAllowed = await ensureGuildComponentMemberAllowed({
467+
// Check user allowlist before processing component interaction
468+
// This prevents unauthorized users from injecting system events.
469+
const allowed = await ensureAgentComponentInteractionAllowed({
470+
ctx: this.ctx,
442471
interaction,
443-
guildInfo,
444472
channelId,
445473
rawGuildId,
446-
channelCtx,
447474
memberRoleIds,
448475
user,
449476
replyOpts,
450477
componentLabel: "button",
451478
unauthorizedReply: "You are not authorized to use this button.",
452479
});
453-
if (!memberAllowed) {
480+
if (!allowed) {
454481
return;
455482
}
483+
const { parentId } = allowed;
456484

457485
// Resolve route with full context (guildId, proper peer kind, parentPeer)
458486
const route = resolveAgentRoute({
@@ -537,28 +565,22 @@ export class AgentSelectMenu extends StringSelectMenu {
537565
memberRoleIds,
538566
} = interactionCtx;
539567

540-
// Check user allowlist before processing component interaction
541-
const guildInfo = resolveDiscordGuildEntry({
542-
guild: interaction.guild ?? undefined,
543-
guildEntries: this.ctx.guildEntries,
544-
});
545-
const channelCtx = resolveDiscordChannelContext(interaction);
546-
const { parentId } = channelCtx;
547-
const memberAllowed = await ensureGuildComponentMemberAllowed({
568+
// Check user allowlist before processing component interaction.
569+
const allowed = await ensureAgentComponentInteractionAllowed({
570+
ctx: this.ctx,
548571
interaction,
549-
guildInfo,
550572
channelId,
551573
rawGuildId,
552-
channelCtx,
553574
memberRoleIds,
554575
user,
555576
replyOpts,
556577
componentLabel: "select",
557578
unauthorizedReply: "You are not authorized to use this select menu.",
558579
});
559-
if (!memberAllowed) {
580+
if (!allowed) {
560581
return;
561582
}
583+
const { parentId } = allowed;
562584

563585
// Extract selected values
564586
const values = interaction.values ?? [];

0 commit comments

Comments
 (0)