Skip to content

fix(comms): route Block Comms context-menu item through panel chrome (#1395) - #1399

Merged
rumblefrog merged 1 commit into
mainfrom
fix/1395-block-comms-context-menu-route
May 17, 2026
Merged

rumblefrog merged 1 commit into
mainfrom
fix/1395-block-comms-context-menu-route

Conversation

@rumblefrog

Copy link
Copy Markdown
Member

Fixes #1395.

Summary

  • The public servers list's right-click context menu's Block Comms item routed to pages/admin.blockit.php?check=…&type=0 — the post-Actions.CommsAdd rcon-fan-out iframe target, NOT a stand-alone operator page. Hitting it directly rendered chromeless full-page and its relative POST resolved to /pages/api.php → 404 (the reporter's exact reproduction).
  • Routes Block Comms through the panel-chromed ?p=admin&c=comms&steam=…&type=0 URL — mirrors the Ban Player sibling that #PLAYER_CTX_MENU shipped on ?p=admin&c=bans&section=add-ban&steam=…&type=0. Both surfaces now land the operator on the real form with the SteamID pre-populated server-side via the View DTO so the affordance works on the no-JS path. Kick stays on the iframe path (pages/admin.kickit.php) because it's a one-shot RCON command with no persistent panel surface to anchor on after firing.
  • admin.blockit.php and admin.kickit.php are untouched — they remain load-bearing as the post-Actions.{CommsAdd,BansAdd} iframe targets for fanning the block/kick out via RCON to every enabled server.

Files changed

  • web/pages/admin.comms.php — new ?steam=…&type=… smart-default block mirroring admin.bans.php's allowlist (regex covers STEAM_X:Y:Z, [U:1:N], 17-digit SteamID64, dotted IPv4). type allowlisted to {1,2,3} (Mute / Gag / Silence); anything else (including the menu's ?type=0 bridging value) falls back to 0 = "no pre-selection" so the form's <select> lands on its native first-option default (Mute).
  • web/includes/View/AdminCommsAddView.php — new readonly properties prefill_steam: string + prefill_type: int.
  • web/themes/default/page_admin_comms_add.tpl — value="{$prefill_steam}" on the steam input + conditional selected on each type <option>. Smarty auto-escape is the belt-and-braces over the PHP-side allowlist.
  • web/scripts/server-context-menu.js — Block Comms href now points at index.php?p=admin&c=comms&steam=…&type=0; JSDoc updated to explain the panel-route vs iframe-route split (Ban + Block panel-routed via the smart-default URL → View DTO; Kick stays on the iframe because it's a one-shot RCON command).
  • web/tests/integration/AdminCommsAddSmartDefaultTest.php — new process-isolated render harness (24 tests / 57 assertions) mirroring AdminBansAddSmartDefaultTest's shape: SteamID2 / SteamID3 / SteamID64 / IPv4 prefill, type pre-selection for {1,2,3}, type-coercion for {0,4,-1,99,empty}, 10 hostile/malformed payload rejections, bare URL + type-without-steam passthrough.
  • web/tests/e2e/specs/flows/server-player-context-menu.spec.ts — strict anchored regex assertions on all three menu items' hrefs (Kick = pages/admin.kickit.php?check=…&type=0; Ban = index.php?p=admin&c=bans&section=add-ban&steam=…&type=0; Block = index.php?p=admin&c=comms&steam=…&type=0) + rationale comment explaining the three routing modes.
  • AGENTS.md — #PLAYER_CTX_MENU Conventions block + "server-player right-click context menu" row in "Where to find what" updated with the new Ban / Block / Kick routing split + the new AdminCommsAddSmartDefaultTest regression-guard cross-reference + the per-surface allowlist contract.

Test plan

All quality gates green:

  • ./sbpp.sh phpstan — clean (level 5 + dba).
  • ./sbpp.sh test — 665 tests pass (24 new in AdminCommsAddSmartDefaultTest); existing AdminBansAddSmartDefaultTest still green.
  • ./sbpp.sh ts-check — clean.
  • ./sbpp.sh composer api-contract — no diff (no JSON-action surface changed).
  • ./sbpp.sh e2e --grep "context-menu|comms" — 29 passed, 35 skipped (per project gating).
  • ./sbpp.sh e2e (full) — 266 passed, 278 skipped; two earlier transient flakes on unrelated specs (smoke/admin/home.spec.ts, flows/server-refresh-debounce.spec.ts) both pass in isolation and neither touches the code paths in this PR.
  • Plugin build gate: N/A (no .sp touched).
  • Prod Docker image gate: N/A (release-only; no docker/ files touched).

Reproduction:

  1. Log in as an admin with ADMIN_OWNER or ADMIN_ADD_BAN.
  2. Open ?p=servers, expand a server with players, right-click a player row.
  3. Click Block Comms → lands on the panel-chromed ?p=admin&c=comms with the SteamID pre-populated in the form (previously: chromeless /pages/admin.blockit.php with a 404 on submit).

…1395)

The "Block Comms" right-click item on the public servers list pointed at
`pages/admin.blockit.php?check=…&type=0` — the post-`Actions.CommsAdd` rcon
fan-out iframe, NOT a stand-alone operator surface. Hitting it directly
rendered chromeless full-page and its relative POST resolved to
`/pages/api.php` → 404.

Restoring parity with the sibling "Ban Player" item by routing Block Comms
through the panel-chromed Add-Ban-style smart-default URL:
`index.php?p=admin&c=comms&steam=<sid>&type=0`.

- `web/pages/admin.comms.php`: new `?steam=…&type=…` smart-default block
  mirroring `admin.bans.php`'s allowlist (regex covers `STEAM_X:Y:Z`,
  `[U:1:N]`, 17-digit SteamID64, dotted IPv4). `type` is allowlisted to
  `{1,2,3}` (Mute / Gag / Silence); anything else (including the menu's
  `?type=0` bridging value) means "no pre-selection".
- `web/includes/View/AdminCommsAddView.php`: new readonly properties
  `prefill_steam: string` + `prefill_type: int`.
- `web/themes/default/page_admin_comms_add.tpl`: `value="{$prefill_steam}"`
  on the steam input + conditional `selected` on the type `<option>`s.
- `web/scripts/server-context-menu.js`: Block Comms href now points at
  `index.php?p=admin&c=comms&steam=…&type=0`; JSDoc updated to explain
  the panel-route vs iframe-route split (Kick stays on the iframe because
  it's a one-shot RCON command with no persistent panel surface).
- `web/tests/integration/AdminCommsAddSmartDefaultTest.php`: new
  process-isolated render harness (24 tests / 57 assertions) covering
  SteamID2 / SteamID3 / SteamID64 / IPv4 prefill, type coercion, hostile
  / malformed input rejection, bare URL passthrough.
- `web/tests/e2e/specs/flows/server-player-context-menu.spec.ts`: updated
  Block Comms href assertion to the new panel-route shape; updated the
  rationale comment to explain the three routing modes.
- `AGENTS.md`: updated #PLAYER_CTX_MENU block + "server-player right-click
  context menu" row in "Where to find what" with the new Ban / Block /
  Kick routing split + new `AdminCommsAddSmartDefaultTest` regression
  guard cross-reference.

`admin.blockit.php` is unchanged — it remains load-bearing as the
post-`Actions.CommsAdd` iframe target for fanning the block out via RCON
to every enabled server. Same for `admin.kickit.php` (post-`Actions.BansAdd`
fan-out, plus the Kick menu item's surviving direct-hit path).

Quality gates: phpstan / phpunit (665 tests pass, 24 new) / ts-check /
api-contract / e2e (266 passed, 278 skipped per project gating); two
unrelated pre-existing flakes on different runs (smoke admin-home,
server-refresh-debounce) — both pass in isolation, neither touches the
code paths in this PR.
@rumblefrog
rumblefrog added this pull request to the merge queue May 17, 2026
Merged via the queue into main with commit b711278 May 17, 2026
5 checks passed
@rumblefrog
rumblefrog deleted the fix/1395-block-comms-context-menu-route branch May 17, 2026 18:48
@github-actions github-actions Bot locked and limited conversation to collaborators May 17, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2.0 rc3 - Server List - expanded card

1 participant