fix(api/v1): scope category lookup to event_owned or global
PR review pointed out the original lookup
db('photo_categories').where({ id: parsedCategoryId }).first()
accepted any category id — including one that belongs to a different
event. photo_categories carries both event_id (per-event) and is_global
(see backend/migrations/legacy/004_add_categories_and_cms.js); the v1
upload route should require either match.
Not a privilege issue (apiTokenAuth.js inherits the admin's powers, no
per-event scoping), but it lets a misconfigured uploader silently file
photos under a category the target event doesn't own — and the 201 echo
includes a category_id that makes no semantic sense.
Tighten to:
.where({ id: parsedCategoryId })
.andWhere(function () {
this.where({ event_id: event.id }).orWhere('is_global', true);
})
…and update the 400 message to "Unknown or out-of-scope category_id N".
OpenAPI description already documents the intended scope.
Tests deferred to a follow-up; v1 has no jest harness today, see PR
discussion.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -385,9 +385,22 @@ router.post(
|
||||
let categoryId = null;
|
||||
let photoType = 'individual';
|
||||
if (!Number.isNaN(parsedCategoryId)) {
|
||||
const category = await db('photo_categories').where({ id: parsedCategoryId }).first();
|
||||
// Scope to categories owned by this event (event_id = event.id) or
|
||||
// marked global (is_global = true) — see migration
|
||||
// backend/migrations/legacy/004_add_categories_and_cms.js. An API
|
||||
// token inherits its owning admin's powers (no per-event scoping
|
||||
// in apiTokenAuth), so accepting any category_id would silently
|
||||
// mis-file uploads under a category belonging to a different event.
|
||||
const category = await db('photo_categories')
|
||||
.where({ id: parsedCategoryId })
|
||||
.andWhere(function () {
|
||||
this.where({ event_id: event.id }).orWhere('is_global', true);
|
||||
})
|
||||
.first();
|
||||
if (!category) {
|
||||
return res.status(400).json({ error: `Unknown category_id ${parsedCategoryId}` });
|
||||
return res.status(400).json({
|
||||
error: `Unknown or out-of-scope category_id ${parsedCategoryId}`,
|
||||
});
|
||||
}
|
||||
categoryId = category.id;
|
||||
if (category.slug === 'collage' || category.slug === 'collages') {
|
||||
|
||||
Reference in New Issue
Block a user