Auth UI: register, login, logout (incl. POST /api/register) #52
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
research
wontfix
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Reference: lvl0/buckets#52
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
The cookie-session auth backend exists (#30:
json_loginon/api/login, firewall logout on/api/logout,/api/me), but there is no frontend for it and no register endpoint yet.Useris deliberately off API Platform (#30 decision), so register needs a small dedicated endpoint.This is a full-stack vertical slice: the register backend + all three auth screens. It sits between #33 (SPA scaffold) and the scenario/bucket content tickets — you can't reach a scenario page without being logged in.
Scope
Backend
POST /api/register— create aUser(email + password), hash via the configured password hasher, reject duplicate email (validation, not 500). NOT via API Platform (User stays off it) — a small dedicated controller/action, JSON in/out, returns 201 or 422. Pin: happy-path 201, duplicate-email 422, missing/invalid fields 422, weak/short password rejected.Frontend (depends on #33 scaffold: router + API client + auth context)
POST /api/register, then auto-login or redirect to login.POST /api/login(json_login), store auth state in context, redirect to scenario list.POST /api/logout(firewall, returns 204), clear auth context, redirect to login.Notes / gotchas
/api/meis the "am I logged in?" probe.Content-Type: application/ld+jsonfor API Platform resources, but/api/login//api/registerare NOT AP resources — confirm their expected content-type (json_login takesapplication/json).Out of scope
Testing
Resolved on
release/v0.3.0(15 commits — a full-stack vertical slice). pr-reviewer (full-ticket diff): Request Changes → the one blocker fixed → green.Backend
POST /api/register— dedicated plain controller (Userstays off API Platform) +RegisterRequestDTO:NotBlank/Email/Length+#[UniqueEntity](duplicate email → 422, not a DB 500). ManualValidatorInterface→{errors:{field:[msgs]}}422 /201 {id,email}(never the hash), no session established. Absent-key guard (?? '') keeps a missing field a 422, not a 500. Reachable unauthenticated. 10 functional tests.Frontend (the auth experience + the patterns #53–#59 build on)
/api/me,login()/logout()flip/clear auth state; logout clears regardless of network outcome.RequireAuth/RequireGuestas layout routes via<Outlet/>) —loading→nullno-flash; redirect via state-flip, not imperative nav.createBrowserRouterroute-objects inrouter.tsx(real config smoke-tested viacreateMemoryRouter)./login(no auto-login), per-field 422 errors. Cross-links between login↔register. Split layouts (bare guest vs authed-with-logout).Input,FieldError+parseFieldErrors(shared field-error pattern),api.postJson(application/json — json_login rejects ld+json).E2E
Containerized Playwright (host-run failed on NixOS →
mcr.microsoft.com/playwrightimage as a profile-gated compose service, targetsfrontend:5173, gated on a frontend healthcheck). One register→login→logout smoke test, green.Infra
npm pinned via a single
NPM_VERSIONin root.env→ both dev Dockerfiles.dev-fe-*/dev-e2e/dev-check/dev-check-allshell helpers.238 backend tests + 33 frontend tests + the e2e all green; PHPStan + oxlint + Prettier clean.
Spawned: #62 (coverage gaps + threshold + enable TS strict), #63 (rename backend
dev-*→dev-be-*), and notes on #35 (php healthcheck + e2e-in-CI + prod APP_DEBUG).