Files
summercms/.planning/phases/07-user-plugin-and-authentication/07-04-SUMMARY.md
2026-09-22 18:09:31 +02:00

4.7 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
07-user-plugin-and-authentication 04 auth
fonoteka
api-token
locale
parity
phase provides
07-user-plugin-and-authentication JWT guard, locale.from-principal, inv.must-change-password
MintPersonalToken and RevokeToken
POST/GET/DELETE /_fonoteka/api/v1/tokens
GET/PUT /_fonoteka/api/v1/me/locale
route-table proof that me/locale is the 423 exemption
07-05
07-06
added patterns
inv_ prefix plus sha256 hex shared with TokenGuard
me/locale group without the password lock
created modified
../fonoteka.go/plugins/golem15/fonoteka/classes/auth/api_token_manager.go
../fonoteka.go/plugins/golem15/fonoteka/controllers/api/token_api_controller.go
../fonoteka.go/plugins/golem15/fonoteka/controllers/api/me_locale_controller.go
../fonoteka.go/plugins/golem15/fonoteka/routes.go
../fonoteka.go/parity/manifest.yaml
Personal token secrets are inv_ plus raw url-safe base64, hashed the same way TokenGuard verifies
me/locale is the only /_fonoteka/api/v1 route without inv.must-change-password
Empty preferred_locale is JSON null
Pattern: token list and locale responses send Cache-Control no-cache, private
Pattern: a missing or foreign token id is the same 404
75min 2026-09-22

Phase 7 Plan 04: Personal tokens and locale Summary

Personal API tokens can be minted, listed, and revoked, and me/locale stays reachable while the password-change lock returns 423 everywhere else on /_fonoteka/api/v1.

Performance

  • Duration: 75 min
  • Started: 2026-09-22T14:50:00Z
  • Completed: 2026-09-22T16:05:00Z
  • Tasks: 3
  • Files modified: 16

Accomplishments

  • MintPersonalToken returns an inv_ secret whose sha256 hex matches TokenGuard. Revoke stamps revoked_at.
  • POST /tokens rejects a scope outside read, write, and ai before insert. GET /tokens omits the secret. DELETE /tokens/{id} is owner-scoped.
  • GET/PUT /me/locale persist pl or en. A locked user can still change locale and gets 423 on genres.
  • The five routes replay as status: ported. The corpus is 7 ported and 147 pending out of 154.

Task Commits

  1. Task 1: Mint and revoke — 3c53bf8 in fonoteka.go
  2. Task 2: Token and locale HTTP — 58fcb45 in fonoteka.go
  3. Task 3: Exempt-route proof and parity flip — fa95534 in fonoteka.go

Files Created/Modified

  • plugins/golem15/fonoteka/classes/auth/api_token_manager.go — mint and revoke
  • plugins/golem15/fonoteka/controllers/api/token_api_controller.go — store, index, destroy
  • plugins/golem15/fonoteka/controllers/api/me_locale_controller.go — show and update
  • plugins/golem15/fonoteka/routes.go — locale middleware placement
  • parity/manifest.yaml — five routes marked ported

Decisions Made

The captured POST /tokens body was a debug HTML 500 from an empty name. The Go handler returns 422 {"error":"Validation failed","errors":{"name":["The name field is required."]}}, and the fixture now records that.

GET /tokens was a capture of a live parity-mcp row. Replay uses the genres seed token Parity MCP with scope read, and the fixture follows that seed.

Deviations from Plan

Auto-fixed Issues

1. [Rule 1 - Bug] Nil validation map panicked on a bad scope

  • Found during: Task 2
  • Issue: lagoon.Validate returns a nil map when name is valid, and assigning errs["scopes"] panicked into an opaque 500.
  • Fix: Allocate the map before recording the scope error.
  • Files modified: controllers/api/token_api_controller.go
  • Committed in: 58fcb45

2. [Rule 1 - Bug] created_at used a Z suffix

  • Found during: Task 3
  • Issue: Tide accepts only Carbon +00:00 timestamps. time.RFC3339 emits Z.
  • Fix: Format token timestamps as 2006-01-02T15:04:05-07:00.
  • Files modified: controllers/api/token_api_controller.go
  • Committed in: fa95534

Total deviations: 2 auto-fixed Impact on plan: Bad scopes stay 422. Token timestamps match the parity normalizer.

Issues Encountered

None

User Setup Required

None - no external service configuration required.

Next Phase Readiness

Ready for 07-05, which starts by recording the isolated PHP instance. AUTH-03 and AUTH-04 stay unchecked until the phase requirement is signed off.

Self-Check: PASSED

  • TestMintPersonalToken, TestTokenApi, TestMeLocale, and TestRequirePasswordChangeExemptSet passed.
  • go test ./parity/ -run 'TestParityCorpus|TestParityContract' passed with 7 ported routes.
  • Commits 3c53bf8, 58fcb45, and fa95534 are on fonoteka.go master.