fix(player): open the player self-service surface to staff #94

Merged
whitlocktech merged 1 commits from fix/staff-player-self-service into main 2026-07-22 08:36:15 +00:00
Member

Problem

A staff account (admin/editor/moderator) that also has linked game characters got a 403 on its own player game-data (e.g. GET /player/shard/accounts), because the whole /player/* group ran requireRole('player'). On the Android client this hid the "My characters" menu and greyed the personal notification streams for staff, even with linked characters.

This contradicts the original design — staff are a superset of players (all player abilities + staff tools on top), which is why the same self-scoped handlers are already mirrored under /admin/shard/*.

Fix

  • player.routes.js: requireRole('player')requireAuth only. Every handler is already self-scoped to the caller by req.user.id (with the pre-existing isAdmin bypass still letting a genuine admin read any character), so this only ever widens access to the caller's own data.
  • Corrected the five stale 403 "Player role required" swagger descriptions and regenerated swagger-output.json.
  • New test/playerRouteAccess.test.js mounts the router and asserts player/admin/editor/moderator all reach the handler, anon still 401s, and a disabled account still 403s.

Tests: 420 pass (6 new).

Coordinated change

  • docs: RunicGateway/docsdocs/staff-player-self-service
  • app: RunicGateway/Android-appfix/staff-player-menu (reveals the player menu items for staff; relies on this 200)

🤖 Generated with Claude Code

AI-assisted: authored with Claude Code (Opus 4.8).

## Problem A staff account (admin/editor/moderator) that also has linked game characters got a **403** on its own player game-data (e.g. `GET /player/shard/accounts`), because the whole `/player/*` group ran `requireRole('player')`. On the Android client this hid the "My characters" menu and greyed the personal notification streams for staff, even with linked characters. This contradicts the original design — staff are a **superset** of players (all player abilities + staff tools on top), which is why the same self-scoped handlers are already mirrored under `/admin/shard/*`. ## Fix - `player.routes.js`: `requireRole('player')` → `requireAuth` only. Every handler is already self-scoped to the caller by `req.user.id` (with the pre-existing `isAdmin` bypass still letting a genuine admin read *any* character), so this only ever widens access to the caller's **own** data. - Corrected the five stale `403 "Player role required"` swagger descriptions and regenerated `swagger-output.json`. - New `test/playerRouteAccess.test.js` mounts the router and asserts player/admin/editor/moderator all reach the handler, anon still 401s, and a disabled account still 403s. **Tests:** 420 pass (6 new). ## Coordinated change - docs: `RunicGateway/docs` → `docs/staff-player-self-service` - app: `RunicGateway/Android-app` → `fix/staff-player-menu` (reveals the player menu items for staff; relies on this 200) 🤖 Generated with [Claude Code](https://claude.com/claude-code) AI-assisted: authored with Claude Code (Opus 4.8).
wtclaude added 1 commit 2026-07-22 08:26:11 +00:00
fix(player): open the player self-service surface to staff
All checks were successful
PR Checks / bot-install (pull_request) Successful in 18s
PR Checks / client-build (pull_request) Successful in 27s
PR Checks / server-tests (pull_request) Successful in 9m28s
14dfc122ba
Staff are a superset of players — every player ability plus their staff
tools on top — but the /player/* group ran requireRole('player'), so a
signed-in admin/editor/moderator got 403 on their own linked game
accounts (e.g. GET /player/shard/accounts). On the Android client this
hid "My characters" and greyed the personal notification streams for
staff accounts, even when they had linked characters.

Drop the role gate: the group is now requireAuth-only. Every handler is
already self-scoped to the caller by req.user.id (with the pre-existing
isAdmin bypass still letting a genuine admin read any character), so this
only ever widens access to the caller's OWN data. Staff also reach the
identical self-scoped handlers under /admin/shard/* (same controller).

- player.routes.js: requireRole('player') -> requireAuth; corrected the
  five stale "Player role required" 403 descriptions and regenerated
  swagger-output.json.
- New test/playerRouteAccess.test.js mounts the router and asserts
  player/admin/editor/moderator all reach the handler, anon still 401s,
  and a disabled account still 403s. Suite: 420 pass.

Co-Authored-By: Claude <noreply@anthropic.com>
whitlocktech approved these changes 2026-07-22 08:29:54 +00:00
whitlocktech scheduled this pull request to auto merge when all checks succeed 2026-07-22 08:29:58 +00:00
whitlocktech merged commit 4f1a4902e8 into main 2026-07-22 08:36:15 +00:00
whitlocktech deleted branch fix/staff-player-self-service 2026-07-22 08:36:16 +00:00
Sign in to join this conversation.
No description provided.