handleButton routed claim_ticket, close_ticket, confirm_close /
confirm_close_with_email / confirm_close_no_email, cancel_close,
escalate_ticket, escalate_to_tier2, escalate_to_tier3, deescalate_ticket,
and confirm_delete_tag::* straight to their handlers without any staff
check. Any non-staff member with View Channel on a ticket — the ticket
creator themselves, or anyone /add'd to it — could click those buttons
and mutate ticket state (claim, escalate, close, delete saved-response
tags).
The slash-command dispatcher in handlers/commands/index.js already
calls requireStaffRole before invoking any handler; the button
dispatcher needed the same gate. Now:
- confirm_delete_tag::<name> → requireStaffRole, then proceed.
- TICKET_BUTTON_HANDLERS dispatch → requireStaffRole, then proceed.
- FREE_BUTTON_HANDLERS (open_ticket* panel buttons, cancel_delete_tag)
remain ungated — those are public-facing by design.
requireStaffRole replies ephemerally ("This command is only available
to the support team (<@&role>)") and returns true when the caller
should bail, matching the slash-command behavior.
30 KiB
30 KiB