Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 26 additions & 8 deletions .agents/skills/kitcn/references/features/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ All from `kitcn/react`:
|------|---------|-------------|
| `useAuth()` | `{ hasSession, isAuthenticated, isLoading }` | Full auth state |
| `useMaybeAuth()` | `boolean` | Has token (optimistic, may not be verified) |
| `useIsAuth()` | `boolean` | Server-verified authentication |
| `useIsAuth()` | `boolean` | Server-verified authentication (with `optimisticAuth`, also during the optimistic window) |
| `useAuthGuard()` | `() => boolean` | Guard mutations, returns true if blocked |
| `useConvexAuthRecovery()` | `{ recover, status, error }` | Rebind Convex auth after a transient token failure |

Expand All @@ -389,7 +389,7 @@ All from `kitcn/react`:
| Component | Renders when |
|-----------|-------------|
| `MaybeAuthenticated` | Has session token (optimistic) |
| `Authenticated` | Server-verified authenticated |
| `Authenticated` | Server-verified authenticated (with `optimisticAuth`, also during the optimistic window) |
| `MaybeUnauthenticated` | No session token (optimistic) |
| `Unauthenticated` | Server-verified not authenticated |

Expand All @@ -414,16 +414,34 @@ All from `kitcn/react`:
```

`optimisticAuth` only opens auth-bound query gates for a held, unexpired JWT;
expired, opaque, and refused tokens stay closed. Enable
expired, opaque, and refused tokens stay closed. The window ends at the Convex
client's first auth result; use one `optimisticAuth` setting per client; no
optimism over a client the Start loader authenticated. Enable
`onTokenIdentityChange` to refuse a JWT whose `sub` or `sessionId` differs from
the document identity before Convex or HTTP sees it. The client closes before
the callback runs, so reload the document there.
the document identity (whatever its `exp`) before Convex, HTTP or the Start
loader sees it. On a trip, every mounted provider hands out no token and
publishes unauthenticated; each guarded one closes its client, then calls the
callback once, so reload the document there. Browser only, page-wide: later
providers start tripped, and a guarded one that mounts or shows again on a
tripped page also closes its client and calls the callback once. Enabling the
guard on a tripped page delivers that close and callback once too; sign-in
mutations fail with `TOKEN_IDENTITY_CHANGED`.

For multiple provider mounts, pass `tokenIdentityBaseline` as
`sub|sessionId`, or a getter returning the document's current identity. The
getter is checked for every admission, cached tokens included.
`sub|sessionId`, or a getter returning the document's current identity. Every
admission (SSR, fresh and cached tokens, sign-in, HTTP, Start loader) binds a
token to the page identity, the provider's own baseline and every mounted
provider's current getter answer; an opaque session token is only exchanged,
never handed to Convex. Held tokens are reconciled when a provider joins the
page and at every admission. A page that never enables the guard is
unchanged; once a guarded provider establishes the page identity it persists
until reload, binding every provider and the Start loader, even after that
provider unmounts. Two kitcn versions or revisions on one page (dev HMR
across revisions included) are unsupported: no shared page identity until
reload.
`onTokenIdentityAdmitted(token)` observes admitted JWTs so the app can update
that shared baseline. All three identity options require
that shared baseline. Admission rechecks the baseline after the callback before
publishing or handing out the token. All three identity options require
`onTokenIdentityChange`.

For `@convex-dev/auth` (React Native):
Expand Down
19 changes: 19 additions & 0 deletions .changeset/harden-auth-identity-guard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
"kitcn": patch
---

## Patches

- Fix `onTokenIdentityChange` letting a token of another user or session into
the auth store, Convex, cRPC HTTP headers or the TanStack Start loader: the
SSR token, restored sessions, sign-in tokens, JWTs without `exp` and
concurrent first tokens are all held to the page's identity and every
mounted provider's current `tokenIdentityBaseline` getter, including changes
made by `onTokenIdentityAdmitted` before publication.
- Fix an identity guard trip staying local to one provider: every mounted
provider now hands out no token and publishes unauthenticated, each guarded
one closes its client and calls `onTokenIdentityChange` once, including a
guard enabled after the trip, and sign-in
mutations fail with `TOKEN_IDENTITY_CHANGED` until the page reloads.
- Fix the `optimisticAuth` window reopening after Convex refused a token: it
now ends at the Convex client's first auth result.
Loading
Loading