fix(08): revise oauth plans after checker feedback
This commit is contained in:
@@ -58,28 +58,58 @@ Output: JWT consent controllers/routes, assembled flow tests, and an external re
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 1: Specify assembled consent and route behavior in executable RED</name>
|
||||
<files>../fonoteka.go/plugins/golem15/fonoteka/controllers/api/oauth_consent_controller_test.go, ../fonoteka.go/plugins/golem15/fonoteka/oauth_connect_test.go</files>
|
||||
<read_first>
|
||||
.planning/phases/08-oauth2-1-authorization-server/08-UI-SPEC.md
|
||||
.planning/phases/08-oauth2-1-authorization-server/08-PATTERNS.md
|
||||
wristband/authorize.go
|
||||
wristband/token.go
|
||||
../fonoteka.go/plugins/golem15/fonoteka/controllers/api/token_api_controller.go
|
||||
../fonoteka.go/plugins/golem15/fonoteka/routes.go
|
||||
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/controllers/api/OAuthConsentController.php
|
||||
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/tests/security/OAuthConsentScopeCeilingTest.php
|
||||
</read_first>
|
||||
<behavior>
|
||||
- Show/allow/deny cover exact 200/404/422 payloads, host-only redirect, canonical scopes, active collection, ownership, and ordered redirects.
|
||||
- Tests compile and fail only through `PHASE8_RED:consent`.
|
||||
- Controller and assembled tests compile and fail only through their exact consent RED sentinels.
|
||||
</behavior>
|
||||
<action>D-18: add controller and assembled PKCE flow tests against 08-04 interfaces. Use `PHASE8_RED:consent` only for absent controller/route behavior and reject syntax/setup/missing-test failures via the RED verifier. Cover T-08-CROSS-USER, SCOPE-CEILING, REQUEST-LEAK, and SURFACE, including duplicate action single-use.</action>
|
||||
<action>D-18: add controller and assembled PKCE flow tests against 08-04 interfaces. Use exact `TestPhase8RedConsentController`/`PHASE8_RED:consent-controller` and `TestPhase8RedConsentApp`/`PHASE8_RED:consent-app` package/test/sentinel triples with `go test -json`; reject every unexpected failing action/package/test, compile/setup/panic/no-test case, and missing/duplicate sentinel. Cover T-08-CROSS-USER, SCOPE-CEILING, REQUEST-LEAK, and SURFACE, including duplicate action single-use.</action>
|
||||
<verify>
|
||||
<automated>scripts/check-phase8-red.sh consent bash -lc "cd ../fonoteka.go && go test ./plugins/golem15/fonoteka/... -run 'TestOAuth(Authorize|Consent|Deny|CodeExchange|Surface)' -count=1"</automated>
|
||||
<automated>scripts/check-phase8-red.sh go PHASE8_RED:consent-controller git.golem15.com/golem15/fonoteka/plugins/golem15/fonoteka/controllers/api TestPhase8RedConsentController -- bash -lc "cd ../fonoteka.go && go test -json ./plugins/golem15/fonoteka/controllers/api -run '^TestPhase8RedConsentController$' -count=1" && scripts/check-phase8-red.sh go PHASE8_RED:consent-app git.golem15.com/golem15/fonoteka/plugins/golem15/fonoteka TestPhase8RedConsentApp -- bash -lc "cd ../fonoteka.go && go test -json ./plugins/golem15/fonoteka -run '^TestPhase8RedConsentApp$' -count=1"</automated>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- Each RED invocation observes exactly one selected test failure and its package failure with the exact sentinel; any other failure action is rejected.
|
||||
- Tests assert exact show 200, missing/stale/used/foreign 404, empty-intersection 422, allow/deny redirect bytes, ownership, active collection, ordered scopes, and duplicate-action single use.
|
||||
- Assembled route inspection proves consent paths are JWT+locale+must-change-password only while authorize/token remain raw.
|
||||
</acceptance_criteria>
|
||||
<done>Consent tests compile, execute, and fail only on the intended missing behavior.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 2: Implement owner-bound JWT consent and raw route wiring</name>
|
||||
<files>../fonoteka.go/plugins/golem15/fonoteka/controllers/api/oauth_consent_controller.go, ../fonoteka.go/plugins/golem15/fonoteka/controllers/api/oauth_consent_controller_test.go, ../fonoteka.go/plugins/golem15/fonoteka/plugin.go, ../fonoteka.go/plugins/golem15/fonoteka/routes.go, ../fonoteka.go/plugins/golem15/fonoteka/oauth_connect_test.go</files>
|
||||
<read_first>
|
||||
../fonoteka.go/plugins/golem15/fonoteka/controllers/api/oauth_consent_controller_test.go
|
||||
../fonoteka.go/plugins/golem15/fonoteka/oauth_connect_test.go
|
||||
../fonoteka.go/plugins/golem15/fonoteka/controllers/api/token_api_controller.go
|
||||
../fonoteka.go/plugins/golem15/fonoteka/classes/active_collection.go
|
||||
../fonoteka.go/plugins/golem15/fonoteka/routes.go
|
||||
/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/controllers/api/OAuthConsentController.php
|
||||
/media/nvme/dev/golem15/fonoteka/vue-fonoteka-app/app/stores/fonoteka.ts
|
||||
</read_first>
|
||||
<behavior>
|
||||
- Show returns sanitized client, host-only redirect, ordered mintable scopes, active collection name, and ISO expiry.
|
||||
- Allow grants submitted ∩ requested ∩ ceiling ∩ mintable; deny consumes pending state; both return nonblank ordered redirect_to.
|
||||
</behavior>
|
||||
<action>D-08: implement show/allow/deny in the JWT+locale+must-change-password group using `bouncer.User`, `ResolveActiveCollection`, `lagoon.Validate`, and wristband operations; never accept collection IDs or extra scopes. Collapse missing/stale/used/foreign handles to exact 404 and empty/no-longer-grantable intersection to exact 422. D-09: mount authorize/token in raw routes and only token receives its throttle. D-10 and D-12: add no oauth guard, house middleware, backend Bearer challenge, or RFC 9728 document.</action>
|
||||
<verify>
|
||||
<automated>cd ../fonoteka.go && go test ./plugins/golem15/fonoteka/... -run 'TestOAuth(Authorize|Consent|Deny|CodeExchange|Surface)' -count=1</automated>
|
||||
<automated>(cd ../fonoteka.go && go test ./plugins/golem15/fonoteka/controllers/api ./plugins/golem15/fonoteka -run '^TestOAuth(Consent|Deny|CodeExchange|Surface)' -count=1)</automated>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- Show returns only sanitized client name, host-only redirect, ordered mintable scopes, active collection name, acting user, and ISO expiry; no secret/handle beyond the submitted opaque request id leaks.
|
||||
- Allow grants exactly submitted ∩ requested ∩ client ceiling ∩ mintable and server-derived collection IDs; deny grants none; both consume once and return one nonblank ordered `redirect_to`.
|
||||
- Missing/stale/used/foreign handles have identical exact 404 bytes, empty/no-longer-grantable scope has exact 422, and no state mutation survives a failing transaction.
|
||||
- Route tests prove JWT/raw/personal groups and unchanged Basic/token-surface headers remain isolated.
|
||||
</acceptance_criteria>
|
||||
<done>The unchanged consent client can inspect, allow, or deny one owner-bound request and complete exact PKCE code exchange.</done>
|
||||
</task>
|
||||
|
||||
@@ -94,11 +124,16 @@ Output: JWT consent controllers/routes, assembled flow tests, and an external re
|
||||
/media/nvme/dev/golem15/fonoteka/vue-fonoteka-app/app/components/fonoteka/ConnectedAppsManager.vue
|
||||
/media/nvme/dev/golem15/fonoteka/vue-fonoteka-app/app/stores/fonoteka.ts
|
||||
</read_first>
|
||||
<action>Create a read-only harness outside the Nuxt checkout using its already-installed Playwright runtime. First run `pnpm verify:oauth-return-path` and `pnpm verify:oauth-i18n`. Then boot the unchanged app and intercept API responses to prove: invalid/missing/repeated-first-invalid handles send no oauth/request call; logged-out entry preserves only a validated localized return path; 200, 404, network/error, empty-scope, allow-pending, deny-pending, and one-redirect outcomes render correctly; connected-app error/empty/manual-count/populated/cancel/revoke-pending/success/failure/identical-404 states render correctly. Assert keyboard order, visible 2px focus, dialog trap/Escape/restore, native disabled semantics, checkbox/revoke targets at least 44px, narrow/mobile stacking and no horizontal overflow, and both English/Polish strings with no raw keys. Snapshot the OAuth-related Nuxt paths before/after and fail on any diff; do not write fixtures, snapshots, generated files, or source inside Nuxt.</action>
|
||||
<action>Create a read-only harness outside the Nuxt checkout using its already-installed Playwright runtime. Define focused scenario selectors for invalid/missing/repeated-first-invalid handles; safe localized login return; consent 200/404/network/empty-scope/pending/one-redirect states; connected-app error/empty/manual-count/populated/cancel/revoke pending/success/failure/identical-404 states; keyboard/focus/dialog/disabled/44px/mobile/en-pl assertions. Add `--contract-self-test` that validates scenario completeness, source-path hashes, intercept definitions, and no-write guards without booting browsers/services; reserve the actual return-path/i18n/browser run for 08-10's final checkpoint. Never write inside Nuxt.</action>
|
||||
<verify>
|
||||
<automated>cd /media/nvme/dev/golem15/fonoteka/vue-fonoteka-app && pnpm verify:oauth-return-path && pnpm verify:oauth-i18n && cd /media/nvme/dev/golem15/summercms.io/summercms/summercms.go && node scripts/check-phase8-ui.mjs --focused</automated>
|
||||
<automated>node scripts/check-phase8-ui.mjs --contract-self-test</automated>
|
||||
</verify>
|
||||
<done>The full UI-SPEC state/accessibility/return-path/i18n matrix passes against unchanged Nuxt files, and the harness is callable from the final gate.</done>
|
||||
<acceptance_criteria>
|
||||
- Self-test enumerates every UI-SPEC consent/connected-app state, keyboard/focus/dialog/44px/mobile assertion, English/Polish check, and invalid-handle no-request case exactly once.
|
||||
- Source-hash/no-write guards cover the listed Nuxt component/store/i18n/return-path files and fail on any before/after change.
|
||||
- Harness exposes one final-gate mode that runs existing `verify:oauth-return-path`, `verify:oauth-i18n`, and the real Playwright matrix; Plan 08-10 is its only full execution site.
|
||||
</acceptance_criteria>
|
||||
<done>The harness encodes and self-validates the full UI-SPEC matrix without changing Nuxt; Plan 08-10's sole final gate executes it.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
@@ -124,7 +159,7 @@ Output: JWT consent controllers/routes, assembled flow tests, and an external re
|
||||
|
||||
<verification>
|
||||
- Focused consent/app tests pass under 30 seconds where possible.
|
||||
- UI harness runs at the wave boundary and is invoked again by the final gate.
|
||||
- UI harness contract self-test stays under 30 seconds; the complete browser matrix runs only in 08-10's final blocking checkpoint.
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
Reference in New Issue
Block a user