Commit Graph

12 Commits

Author SHA1 Message Date
2152544d09 escalation/de-escalation: keep ticket creator and /add'd users on the channel
enqueueMove called channel.setParent(categoryId, { lockPermissions: true }).
discord.js's default for setParent is also true. With lockPermissions: true,
Discord re-syncs the channel's permission overwrites to match the new
parent category — so the explicit per-user allows set at ticket creation
(creator) and via /add (extra members) got wiped on every escalate,
de-escalate, and /move. The creator literally lost View Channel on their
own ticket the moment staff hit Escalate.

Flip to lockPermissions: false so the existing channel-level overwrites
are preserved across the parent change. Inheritance still applies for
anything the channel doesn't override — and the deny-@everyone /
role-allow set at creation continues to gate access correctly.

Affects every caller of enqueueMove:
  - handlers/commands/escalation.js runEscalation
  - handlers/commands/escalation.js runDeescalation
  - handlers/commands/index.js handleMove (/move)
2026-05-19 20:09:58 +00:00
452f005aea silence secondary-bot 429 fallback noise from debug channel
Two paired logWarn calls used to post to DEBUGGING_CHANNEL_ID every time
the RENAMER_BOT secondary token hit Discord's per-channel rename quota:

  Warning: renamer        — "429 rename channel=… retry_after=…"
  Warning: renameQueue    — "secondary-bot 429; falling back to primary…"

Both fire on the recoverable path: the channelQueue immediately falls
back to the primary discord.js client, and that client's REST handler
transparently waits out the retry_after and retries — the rename lands
without operator action. Posting these to the debug channel was pure
noise; staff were reading them as failures when nothing had failed.

Demoted both to console.warn so they still appear in `docker logs
broccolini` for diagnostic purposes but no longer post to Discord.

Kept untouched:
- utils/renamer.js:64 — 401/403 logWarn on secondary-bot auth/permission
  errors (real config problems; the operator does need to know).
- services/channelQueue.js next.catch logError for status 401/403/429 —
  only fires when the fallback itself also failed (rare and worth a
  debug-channel post).
2026-05-19 18:38:18 +00:00
cdf85f6364 audit week 1: creator ID tracking, channel-queue migration, deprecation cleanup
QUAL-006  store ticket.creatorId on creation; legacy split-pop returned the
          message ID for discord-msg-* tickets, breaking transcript DM, close
          log, and channel rename for context-menu-created tickets. Adds the
          field to the Ticket schema and writes a one-shot backfill script
          (scripts/backfill-creatorId.js, dry-run by default).

QUEUE-001 add enqueueOverwrite + enqueueTopic to services/channelQueue.js
          (chain on renameChains alongside enqueueMove). Migrate handleAdd /
          handleRemove / handleMove / handleTopic so permissionOverwrites,
          setParent, and setTopic no longer race pending renames or sends.
          handleMove now uses the existing enqueueMove. Initial overwrites in
          handleTicketModal stay inline; channel doesn't exist yet so no race.

DISCORD-001 replace ephemeral: true with flags: MessageFlags.Ephemeral across
            broccolini-discord.js, handlers/sharedHelpers.js, handlers/buttons.js,
            handlers/commands.js. runDeferred opts now take { flags } directly.

SEC-003   /gmailpoll min interval is 30s. Drop the 5s/10s slash-command
          choices and clamp Math.max(30000, ms) in handleGmailPoll for
          defense in depth.

QUAL-001  upgrade silent .catch(() => {}) on the lastActivity updateOne in
          handlers/messages.js to log via logError, so transient Mongo errors
          surface in the debug channel instead of disappearing.

QUAL-002  drop await from logError/logWarn calls in services/staffThread.js
          and services/pinMessage.js — fire-and-forget per CLAUDE.md hard rule.

QUAL-003  wrap stray setTimeouts (handleConfirmCloseRequest force-close timer,
          runFinalClose channel-delete + overflow-cleanup, checkAutoClose
          delete-after-email) in trackTimeout via lazy require so they clear
          on shutdown.
2026-05-08 20:19:14 +00:00
33b1f276c6 audit 2026-04-20 18:05:36 +00:00
d73422555d rename path: fix env-var mismatch, gut canRename gate, add primary-bot fallback on 401/403/429
- secondary rename-bot token was set as RENAME_TOKEN in .env but utils/renamer.js reads RENAMER_BOT; silently no-op'd every rename (host .env renamed separately)
- services/tickets.js canRename gutted to an always-ok shim; Mongo 2/10min per-channel gate is redundant since renames flow through RENAMER_BOT's own bucket. Ticket.renameCount / renameWindowStart remain as orphan fields (no migration)
- handlers/buttons.js + commands.js: drop the four "Channel renamed too quickly" else-branches and the rename-countdown label suffix; replace .catch(() => {}) with .catch(err => logError('rename', err)...)
- services/channelQueue.js: executeRename falls back to channel.setName(currentName) when renamer throws err.fallback === true (401/403/429); classifies non-fallback errors as renameQueue:token/permission (401/403) or renameQueue:secondary-bot ratelimited (429)
- utils/renamer.js: on 401/403 throw err.fallback=true immediately; on 429 respect retry_after up to 2000ms then throw err.fallback=true
- docs: align CLAUDE.md, docs/api/DISCORD_API_VALIDATION.md, docs/architecture/CRITICAL_FILES_AND_HOW_IT_WORKS.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 15:56:06 +00:00
fcce7c3e86 changes 2026-04-20 14:56:55 +00:00
21618efbad security hardening 2026-04-18 11:10:41 +00:00
indifferentketchup
eae801ff7d queue 2026-04-09 14:57:41 -05:00
indifferentketchup
7fff9192b4 queue 2026-04-09 09:49:19 -05:00
indifferentketchup
69c247ed1b huge changes 2026-04-07 01:43:06 -05:00
indifferentketchup
1496a96274 Dynamic overflow categories 2026-03-28 20:55:36 -05:00
indifferentketchup
8a4e306f28 p-queue 2026-03-28 18:39:00 -05:00