test(deploy): add a real login smoke test, not just a health check
Found on the actual first deployment: /api/v1/healthz proves the process is up, but says nothing about whether login actually works, because the session cookie is set with Secure in production. Test through a plain-HTTP address (an IP, a bare port, skipping the reverse proxy) and /auth/login still returns 200 with a valid body — the cookie is just silently dropped by the client, so the very next request looks unauthenticated. From a browser this looks exactly like "I logged in and it bounced me straight back to the login screen," with no error anywhere to point at. scripts/smoke-test.sh does the real round trip a browser does: login, confirm a session cookie was actually stored (not just sent), then an authenticated follow-up request confirming it succeeds and returns the right account. Verified it actually catches what it's meant to catch before committing: ran it against a throwaway account over plain HTTP against a production-mode container and got the expected FAIL with a diagnostic pointing at the Secure-cookie mismatch, then confirmed PASS once the container's VELODROME_ENVIRONMENT was (inadvertently, in this case) development instead. Documented in deploy/README.md as the real post-deploy check, replacing "hit /healthz and eyeball it" for anything involving auth. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R2ZKeWkZV7ehf7fivrAkkG
This commit is contained in:
@@ -78,6 +78,30 @@ Nothing enforces the admin role yet — no admin-only endpoint exists — so tod
|
||||
invited account only in the role recorded on it. Invite management in a later phase is what starts
|
||||
reading it.
|
||||
|
||||
## Verify login actually works, not just that the API responds
|
||||
|
||||
`GET /api/v1/healthz` proves the process is up. It does **not** prove a real login works, because
|
||||
the session cookie is set with `Secure` in production (`apps/api/velodrome/api/v1/auth.py`) —
|
||||
browsers silently refuse to store a `Secure` cookie unless the request was actually served over
|
||||
HTTPS. Test through a plain-HTTP address (an IP, a bare port, skipping the reverse proxy) and
|
||||
`/auth/login` still returns 200 with a valid response body; the cookie is just quietly dropped, so
|
||||
the very next request looks unauthenticated. From a browser this looks exactly like "I logged in
|
||||
and it bounced me straight back to the login screen," with nothing that looks like an error. This
|
||||
happened on the very first real deployment.
|
||||
|
||||
`scripts/smoke-test.sh` exists so this is caught by running a command, not by refreshing a browser
|
||||
tab:
|
||||
|
||||
```sh
|
||||
scripts/smoke-test.sh https://bike.bbergle.com you@example.com yourpassword
|
||||
```
|
||||
|
||||
It logs in, confirms a session cookie was actually stored (not just sent), then makes an
|
||||
authenticated follow-up request and confirms it succeeds and returns the right account. Run it
|
||||
after every real deploy, against the actual public URL your users will use — testing against a
|
||||
plain-HTTP IP will (correctly) tell you nothing about whether login works for anyone using the real
|
||||
domain.
|
||||
|
||||
## Environment variables
|
||||
|
||||
All read by `apps/api/velodrome/config.py` (prefix `VELODROME_`) — the app and Alembic both read
|
||||
|
||||
Reference in New Issue
Block a user