mirror of
https://github.com/screentinker/screentinker.git
synced 2026-08-13 22:03:13 -06:00
GET /api/devices/:id/screenshot returns a live picture of what a screen is showing, but it was still authorized pre-tenancy: `device.user_id !== user.id`, with a role bypass listing 'admin'/'superadmin'. Three consequences, all now covered by tests: - `device.user_id &&` SHORT-CIRCUITED. A device with no user_id — never paired, or its owner deleted — skipped the ownership test entirely, so any authenticated account on the instance could read it. An unpaired panel displays its pairing code on screen, so that image is also a route to claiming the device (AUTH-10, out of scope here but connected). - 'platform_admin' was absent from the bypass list. #14 renamed 'superadmin' to 'platform_admin', so an actual platform admin fell through to the ownership test and was denied unless they happened to own the row. - Workspace members other than the owner were denied a device they administer through every other endpoint. Now uses accessContext() against the device's workspace — the same helper routes/devices.js uses — which covers direct membership, org-level access and platform staff in one call. A device with no workspace is denied outright rather than defaulting open. Deliberately unchanged: the ?token= query-parameter mechanism on this route, which is a separate finding with its own blast radius. No response shape change: still 200 / 401 / 403 / 404 with the same bodies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| config | ||
| db | ||
| lib | ||
| middleware | ||
| player | ||
| routes | ||
| scripts | ||
| services | ||
| test | ||
| ws | ||
| .gitignore | ||
| config.js | ||
| package-lock.json | ||
| package.json | ||
| server.js | ||
| version.js | ||