Reject bingo toggle requests for tiles outside the user's current card
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## Problem
`toggle` verifies that a supplied tile ID exists and is active, but never verifies that the tile is one of the caller current seeded card tiles. Any authenticated user can POST an arbitrary active `tileId` from the global pool to `?/toggle`; a `bingo_progress` row is inserted and a completion activity is logged.
This is visible in standings because `loadStandings` uses `completedIds.size`, which counts every progress row, not just IDs on the displayed card. It also lets players pre-mark tiles that may appear after later pool changes.
## Reproduction
1. Configure more tiles than a single card uses.
2. Sign in and obtain the ID of an active tile that is not on the rendered card.
3. Submit `POST /bingo?/toggle` with that ID.
4. The request succeeds despite no corresponding tile being available to the player; the activity log and leaderboard progress increase.
## Suggested fix
Build the caller current seeded card before insertion or removal and return 400 or 403 unless the requested ID is in it (free space remains a no-op). Count only current-card progress in standings, or deliberately clear or migrate off-card progress when the pool changes.
## Affected code
- `src/routes/bingo/+page.server.ts`
- `src/lib/server/standings.ts`
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in src/routes/bingo/+page.server.ts by tracing toggle and how the caller’s current seeded card is built, then inspect src/lib/server/standings.ts and loadStandings. Verify that off-card tile IDs cannot create or remove progress, free space remains a no-op, and standings count only progress for the current card or apply the chosen pool-change behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- authorization, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100