public: reject non-boolean crew, closing a paid-sale-books-as-free hole

crew ? 0 : total (and crew ? 1 : 0 in the insert) only work correctly if
crew is actually a boolean. Any other truthy value — the string "false"
is the obvious one, but any stray object/number works too — silently
books a paid sale as a free crew drink. Once total_cents is 0 there's
nothing left in the row to tell a genuine crew drink apart from a
mis-typed paid one; unrecoverable after the fact.

Adds the same typeof check the other fields on this endpoint already get
(isValidCents, qty bounds, etc.) — reject with 400 instead of silently
mis-booking.
This commit is contained in:
iris 2026-07-31 09:20:41 +02:00
commit 22aa069b35

View file

@ -55,6 +55,13 @@ export function registerPublicRoutes(app: FastifyInstance, db: DB) {
if (!Number.isInteger(bar_id)) {
return sendProblem(req, reply, 400, 'Bad Request', 'bar_id required');
}
// `crew ? 0 : total` below only works if `crew` is actually a boolean —
// any other truthy value (e.g. the string "false", or a stray object)
// would silently book a paid sale as a free crew drink, with nothing in
// the row afterwards to tell that apart from a genuine crew transaction.
if (crew !== undefined && typeof crew !== 'boolean') {
return sendProblem(req, reply, 400, 'Bad Request', 'crew must be a boolean');
}
if (!Array.isArray(items)) {
return sendProblem(req, reply, 400, 'Bad Request', 'items required');
}