@@ -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+
208242export 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