fix: keep ticket waves when a client edits an event without them
Some checks failed
lint.yml / fix: keep ticket waves when a client edits an event without them (pull_request) Failing after 0s
Some checks failed
lint.yml / fix: keep ticket waves when a client edits an event without them (pull_request) Failing after 0s
`api_event_update` replaces `extra` wholesale, so a client that rebuilds
the envelope rather than round-tripping it destroyed every wave: the list
arrived empty, `ensure_ticket_waves` synthesized a single primary wave
from the event-level `amount_tickets`, and a multi-wave event silently
collapsed into one tier carrying whatever numbers that client sent.
Reproduced against a running instance before fixing — a PUT whose `extra`
omitted the key turned a two-wave event into:
amount_tickets=999 price=77.0 waves=1
primary "Primary wave" 77.0 999
`promo_codes` has carried the same guard since the v1.6.8 merge, for the
same reason and in the same function; `ticket_waves` is the same class of
state — organiser-managed, living in `extra`, and invisible to a client
that does not implement it. I added the first and did not extend the
reasoning to the second.
The carry-over runs before `_validate_wave_capacity` so validation sees
the waves the event will actually end up with; otherwise a client that
omitted both the waves and a real capacity would be rejected for a
zero-capacity primary wave that existed only because its waves had just
been dropped. An explicit `[]` still resets, matching promo codes.
Note the aio webapp is not what surfaced this — it spreads the existing
`extra` and so preserves waves by accident. Any client that does not is
exposed.
6 tests, including one pinning the ordering and one that fails if either
organiser-owned `extra` field loses its guard. 126 pass.
This commit is contained in:
parent
6bdebe4562
commit
064795c62a
2 changed files with 138 additions and 0 deletions
14
views_api.py
14
views_api.py
|
|
@ -416,6 +416,20 @@ async def api_event_update(
|
|||
if event.wallet != wallet.wallet.id:
|
||||
raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not your event.")
|
||||
|
||||
# Carry the stored waves over unless the request names the key. `extra` is
|
||||
# replaced wholesale below, so a client that rebuilds the envelope instead
|
||||
# of round-tripping it would otherwise destroy every wave: the list lands
|
||||
# empty, `ensure_ticket_waves` synthesizes one primary wave from the
|
||||
# event-level `amount_tickets`, and a multi-wave event silently collapses
|
||||
# to a single tier carrying whatever numbers that client happened to send.
|
||||
# Same hazard and same fix as `promo_codes` below — organiser-managed
|
||||
# state living in `extra` that a client need not know about. Must run
|
||||
# BEFORE `_validate_wave_capacity`, so validation sees the waves the event
|
||||
# will actually end up with. An explicit `[]` still resets, as it does for
|
||||
# promo codes.
|
||||
if "ticket_waves" not in data.extra.__fields_set__:
|
||||
data.extra.ticket_waves = event.extra.ticket_waves
|
||||
|
||||
_validate_wave_capacity(data, event)
|
||||
|
||||
from lnbits.settings import settings
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue