81 lines
3.0 KiB
Markdown
81 lines
3.0 KiB
Markdown
---
|
|
id: "01-classify-session-challenges"
|
|
title: "Classify session challenges and preserve PAT errors"
|
|
status: done
|
|
wave: 1
|
|
depends_on: []
|
|
plan: "plan.md"
|
|
spec: "../../specs/auth/requirements/auth.md"
|
|
related_spec: "../../specs/integrations/requirements/github-authentication.md"
|
|
---
|
|
|
|
# Task 01: Classify session challenges and preserve PAT errors
|
|
|
|
## Intent
|
|
|
|
Prevent third-party provider 401 responses from invoking the global Kandev login redirect while
|
|
preserving the redirect for a real Kandev session challenge. Prove that an invalid GitHub PAT save
|
|
remains visible and retryable in the existing connection dialog.
|
|
|
|
## Acceptance
|
|
|
|
1. `fetchJson` invokes `onUnauthorized` only for a 401 carrying Kandev's
|
|
`WWW-Authenticate: Bearer` challenge and still throws `ApiError` for both challenged and
|
|
unchallenged failures.
|
|
2. An unchallenged provider 401 preserves its parsed error message for the calling integration UI.
|
|
3. A PAT-only GitHub connection save failure leaves the dialog open, retains the submitted token,
|
|
displays the error, and does not call the saved callback.
|
|
|
|
## TDD
|
|
|
|
1. Add the challenged/unchallenged 401 unit cases and the PAT-only dialog rejection case.
|
|
2. Run them against current code and confirm the unchallenged-401 case fails because
|
|
`onUnauthorized` is called.
|
|
3. Implement the smallest shared-client classification change.
|
|
4. Rerun the focused tests and refactor only if needed.
|
|
|
|
## Files Likely Touched
|
|
|
|
- `apps/web/lib/api/client.ts`
|
|
- `apps/web/lib/api/client.test.ts`
|
|
- `apps/web/components/github/github-connection-dialog.test.tsx`
|
|
|
|
## Dependencies
|
|
|
|
None.
|
|
|
|
## Parallelism
|
|
|
|
`sequential` — Task 02 depends on this behavior.
|
|
|
|
## Verification
|
|
|
|
```bash
|
|
cd apps && pnpm --filter @kandev/web test -- lib/api/client.test.ts components/github/github-connection-dialog.test.tsx
|
|
```
|
|
|
|
## Inputs
|
|
|
|
- `docs/specs/auth/requirements/auth.md` — session challenge versus provider failure behavior.
|
|
- `docs/specs/integrations/requirements/github-authentication.md` — invalid PAT save behavior.
|
|
- `apps/backend/internal/auth/httpmw/middleware.go` — authoritative Kandev session challenge.
|
|
- `apps/web/src/main.tsx` — global unauthorized callback.
|
|
|
|
## Output Contract
|
|
|
|
Verification record:
|
|
|
|
- RED: before the challenge gate, the focused provider-401 test failed because
|
|
`onUnauthorized` was invoked for an unchallenged 401.
|
|
- Changed files: `apps/web/lib/api/client.ts`,
|
|
`apps/web/lib/api/client.test.ts`, and
|
|
`apps/web/components/github/github-connection-dialog.test.tsx`.
|
|
- Final focused result: 14 tests passed; the managed provider-auth E2E spec passed all 5
|
|
scenarios; web typecheck and changed-file lint passed.
|
|
- Follow-up review fix: `apps/backend/internal/backendapp/middleware.go` now exposes
|
|
`WWW-Authenticate` to split-origin browsers, with a regression test in
|
|
`apps/backend/internal/backendapp/middleware_test.go`.
|
|
- Remaining risk: session redirect classification depends on the backend emitting the
|
|
`WWW-Authenticate: Bearer` challenge; same-origin and split-origin paths now both preserve
|
|
that signal.
|