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

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>
This commit is contained in:
2026-07-22 02:17:29 -05:00
parent 514bc9d23c
commit 14dfc122ba
3 changed files with 111 additions and 21 deletions

View File

@@ -10147,7 +10147,7 @@
}
},
"403": {
"description": "Player role required, or account not active",
"description": "Account not active (disabled/banned)",
"content": {
"application/json": {
"schema": {
@@ -10207,7 +10207,7 @@
"description": "Unauthorized"
},
"403": {
"description": "Player role required, or account not active",
"description": "Account not active (disabled/banned)",
"content": {
"application/json": {
"schema": {
@@ -10292,7 +10292,7 @@
"description": "Unauthorized"
},
"403": {
"description": "Player role required, or account not active",
"description": "Account not active (disabled/banned)",
"content": {
"application/json": {
"schema": {
@@ -11141,7 +11141,7 @@
"description": "Unauthorized"
},
"403": {
"description": "Player role required, or account not active",
"description": "Account not active (disabled/banned)",
"content": {
"application/json": {
"schema": {
@@ -11272,7 +11272,7 @@
"description": "Unauthorized"
},
"403": {
"description": "Player role required, or account not active",
"description": "Account not active (disabled/banned)",
"content": {
"application/json": {
"schema": {