Stable twin of #1071.
Three specs acquire an admin token with `const body = await res.json();
return body.token`. On this branch too the admin login sets the JWT as
the httpOnly `admin_token` cookie and responds with `res.json({ user })`
— verified in auth.js on stable, not assumed from main — so the token is
undefined and each spec fails at its first assertion, before exercising
anything it was written to cover.
Cookie and Authorization: Bearer are interchangeable server-side, so the
helpers read the value back out of the context cookie jar and keep
threading it as a Bearer. Every downstream call is unchanged.
Verification is weaker than the main twin's, deliberately: the three
spec files are byte-identical to the ones measured there (0 passed /
6 failed before, 3 passed / 3 failed after, against a live stack), and
they compile and enumerate on this branch. Standing up a full stable
compose stack to re-measure test-only changes was not worth it — say the
word if you want that done before merge.
The remaining failures are UI staleness, not auth, and are not addressed
here. No CI workflow runs tests/e2e on this branch either, which is why
this rotted unnoticed.
Claude-Session: https://claude.ai/code/session_01Ra4hcsYiKuQLbbRsg6EjAc
Co-authored-by: Paul Nothaft <[email protected]>
When admin/customer emails were configured as optional in Settings >
Event Creation, the backend still rejected empty values because:
1. express-validator .optional() only skips undefined, not empty strings
— changed to .optional({ values: 'falsy' }) so "" is treated as
absent
2. DB columns host_email and admin_email had NOT NULL constraints
— added migration to make them nullable
3. Email queue insert crashed on null recipient_email
— skip queuing when no customer email is provided