Files
summercms/.planning/phases/07-user-plugin-and-authentication/07-05-SUMMARY.md
Jakub Zych fa7bdb5f71 docs(07-05): complete the user API parity capture plan
Record that the 15 user routes stay pending until Go matches the PHP bodies, including the HTML 500 on a bad activation code and the still-valid token after logout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-22 18:44:05 +02:00

129 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
phase: 07-user-plugin-and-authentication
plan: 05
subsystem: auth
tags: [fonoteka, parity, user-api, php]
requires:
- phase: 07-user-plugin-and-authentication
provides: user session, account, token, and locale handlers
provides:
- 15 recorded /_user/api/v1 routes in the parity manifest
- db_capture helper for reset and activation codes
- nuxt-auth and locked-user client flows
affects: [07-06]
tech-stack:
added: []
patterns: [user-api auth group beside the 154 fonoteka routes, code capture through artisan tinker]
key-files:
created:
- ../fonoteka.go/parity/db_capture.go
- ../fonoteka.go/parity/fixtures/nuxt/nuxt-auth.yaml
- ../fonoteka.go/parity/fixtures/nuxt/nuxt-auth-lock.yaml
modified:
- ../fonoteka.go/parity/manifest.yaml
- ../fonoteka.go/parity/capture-rules.yaml
- tide/variables.go
key-decisions:
- "The 15 user routes stay pending until a Go replay matches the recorded PHP body"
- "A sixth failed login is the same 401 as the first; this login path does not suspend"
- "Register disabled and register throttled both record as an opaque 500"
- "Authenticated activate with a wrong code records an HTML 500, and fetch after logout still returns 200"
patterns-established:
- "Pattern: user-api routes are extra manifest IDs; the fonoteka routes.php digest stays the 154-route lock"
- "Pattern: reset and activation codes are read by db_capture and stored as {id}!{code}"
requirements-completed: []
duration: 45min
completed: 2026-09-22
---
# Phase 7 Plan 05: User API parity capture Summary
**The 15 `/_user/api/v1` routes are recorded from the isolated PHP app. They stay pending because several PHP bodies differ from the current Go handlers.**
## Performance
- **Duration:** 45 min
- **Started:** 2026-09-22T16:11:00Z
- **Completed:** 2026-09-22T16:45:00Z
- **Tasks:** 3
- **Files modified:** 45
## Accomplishments
- Recorded login, logout, fetch, refresh, register, forgot-password, reset-password, activate, activate-by-code, update, change-password, avatar, avatar/remove, marketing-consent, and oauth-providers, including validation and auth failures.
- `db_capture` reads `reset_password_code` and `activation_code` through the isolated artisan tinker and stores `{id}!{code}`.
- `nuxt-auth.yaml` walks register, fetch, update, change-password, refresh, logout, and a following fetch. `nuxt-auth-lock.yaml` records 423 on genres, 200 on me/locale, then a successful change-password.
- The corpus audit prints `recorded 169/169`. Ported routes stay at 7. The new routes are pending.
## Task Commits
1. **Task 1–3: Record and verify the user API corpus** — `30984b6` in `fonoteka.go`
2. **Scrubber allow-list for the second test password** — `7d5d865` in `summercms.go`
## Files Created/Modified
- `parity/manifest.yaml` — 15 `auth_group: user-api` entries
- `parity/capture-rules.yaml` — register, refresh, and activate-by-code token capture
- `parity/db_capture.go` — PHP tinker and Postgres code readers
- `parity/fixtures/nuxt/nuxt-auth.yaml` — D-14 session flow
- `parity/fixtures/nuxt/nuxt-auth-lock.yaml` — locked-user 423 then me/locale
- `tide/variables.go` — `parity-alice-next` is an allow-listed test password
## Decisions Made
A2 is settled from the recording. Six rapid failed logins for `a2@parity.test` are all 401 `{"error":true,"message":"Nieprawidłowy email lub hasło"}`. The 6th body equals the 1st. This login path does not suspend the account.
Register with `allow_registration=false` and register after the per-IP limit both record `{"error":"Internal server error"}` at status 500 under `APP_DEBUG=false`.
Every recorded login, fetch, register, and update success user payload contains `feedback_widget_hidden: false`.
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 1 - Bug] Authenticated activate with a wrong code is an HTML 500**
- **Found during:** Task 2
- **Issue:** The plan expected 200 `{"user":...}` with `is_activated` unchanged. PHP `attemptActivation` throws outside the JSON catch, and the isolated app returns the generic HTML page titled "Błąd strony" at status 500. `POST activate-by-code` with `1!nope` does the same.
- **Fix:** The fixtures keep the recorded HTML. The Go handler's 200 is a gap for a later closure, not a fixture edit.
- **Files modified:** `parity/fixtures/routes/POST___user_api_v1_activate_user-api.yaml`, `parity/fixtures/routes/POST___user_api_v1_activate-by-code_user-api__invalid.yaml`
- **Committed in:** `30984b6`
**2. [Rule 1 - Bug] Fetch after logout is still 200**
- **Found during:** Task 2
- **Issue:** The plan expected the logged-out bearer to be refused. PHP logout returns `{"message":"Logged out"}` and a following `GET /fetch` with that bearer is still 200. The Go handler blacklists the token.
- **Fix:** `GET___user_api_v1_fetch_user-api__reused.yaml` and the last step of `nuxt-auth.yaml` record the 200. The routes stay `pending`.
- **Files modified:** `parity/fixtures/routes/GET___user_api_v1_fetch_user-api__reused.yaml`, `parity/fixtures/nuxt/nuxt-auth.yaml`
- **Committed in:** `30984b6`
---
**Total deviations:** 2 recorded, not patched in Go
**Impact on plan:** The corpus matches PHP. Closing the activate and logout gaps is follow-up work, not a silent fixture rewrite.
## Issues Encountered
None
## User Setup Required
None - no external service configuration required.
## Next Phase Readiness
Ready for 07-06 unit coverage. AUTH-01, AUTH-02, AUTH-03, AUTH-04, and I18N-02 stay unchecked until phase sign-off. The user-api routes stay pending until Go matches the recorded bodies.
## Self-Check: PASSED
- Secret grep over the new fixtures found no live JWT or `inv_` token.
- `/tmp/summercms-parity/vars.yaml` is mode 0600 and outside the repo.
- `go run ./parity/check_corpus.go --require-recorded --require-clients --check-secrets` printed `recorded 169/169`.
- `go test ./parity/ -run 'TestParityCorpus|TestDBCapture'` passed with 7 ported and 162 pending.
- Commits `30984b6` and `7d5d865` are on master.