Frontend for pansy's auth: a login page that renders whichever methods the server offers (OIDC button first — Authentik is the primary path — plus local email/password when enabled), a register page for open local signup, and a router-level guard so unauthenticated users land on /login.
Scope
Fetch GET /api/v1/auth/providers on the login page; render the OIDC button (its label comes from the response, e.g. "Sign in with Authentik") linking to /api/v1/auth/oidc/login, and/or the local email+password form. Show ?error= messages from a failed OIDC callback.
Register page (only reachable when local auth is enabled): email, display name, password; friendly handling of "registration closed".
Auth state: a useMe() react-query hook around GET /auth/me; router root guard redirects unauthenticated users to /login (preserving the intended destination) and bounces authenticated users away from /login//register.
Nav: current user's display name + logout button (POST /auth/logout, then invalidate the me-query).
Mobile-friendly forms (sensible autocomplete attributes, no zoom-triggering font sizes).
API wrapper from #2 (web/src/lib/api.ts); zod-parse responses.
Provider endpoint shape defined in #4/#5.
Dependencies
Blocked by #2 and #4. The OIDC button lights up once #5 is deployed but must not require it (renders whatever /auth/providers reports).
Acceptance criteria
With the Go server running (make dev): register → auto-login (or login) → redirected to /gardens; refresh keeps you in; logout returns to /login.
Visiting /gardens/1 logged out redirects to /login and returns you there after login.
With OIDC configured on the server, the button appears and completes the Authentik round trip.
npx tsc --noEmit clean.
Part of epic #20 · Design: [DESIGN.md](https://gitea.stevedudenhoeffer.com/steve/pansy/src/branch/main/DESIGN.md)
## Context
Frontend for pansy's auth: a login page that renders whichever methods the server offers (OIDC button first — Authentik is the primary path — plus local email/password when enabled), a register page for open local signup, and a router-level guard so unauthenticated users land on `/login`.
## Scope
- [ ] Fetch `GET /api/v1/auth/providers` on the login page; render the OIDC button (its label comes from the response, e.g. "Sign in with Authentik") linking to `/api/v1/auth/oidc/login`, and/or the local email+password form. Show `?error=` messages from a failed OIDC callback.
- [ ] Register page (only reachable when local auth is enabled): email, display name, password; friendly handling of "registration closed".
- [ ] Auth state: a `useMe()` react-query hook around `GET /auth/me`; router root guard redirects unauthenticated users to `/login` (preserving the intended destination) and bounces authenticated users away from `/login`/`/register`.
- [ ] Nav: current user's display name + logout button (`POST /auth/logout`, then invalidate the me-query).
- [ ] Mobile-friendly forms (sensible autocomplete attributes, no zoom-triggering font sizes).
## Out of scope
- Account settings/password change (post-v1). Gardens pages (#8).
## Key files & patterns
- API wrapper from #2 (`web/src/lib/api.ts`); zod-parse responses.
- Provider endpoint shape defined in #4/#5.
## Dependencies
Blocked by #2 and #4. The OIDC button lights up once #5 is deployed but must not require it (renders whatever `/auth/providers` reports).
## Acceptance criteria
- With the Go server running (`make dev`): register → auto-login (or login) → redirected to `/gardens`; refresh keeps you in; logout returns to `/login`.
- Visiting `/gardens/1` logged out redirects to `/login` and returns you there after login.
- With OIDC configured on the server, the button appears and completes the Authentik round trip.
- `npx tsc --noEmit` clean.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Part of epic #20 · Design: DESIGN.md
Context
Frontend for pansy's auth: a login page that renders whichever methods the server offers (OIDC button first — Authentik is the primary path — plus local email/password when enabled), a register page for open local signup, and a router-level guard so unauthenticated users land on
/login.Scope
GET /api/v1/auth/providerson the login page; render the OIDC button (its label comes from the response, e.g. "Sign in with Authentik") linking to/api/v1/auth/oidc/login, and/or the local email+password form. Show?error=messages from a failed OIDC callback.useMe()react-query hook aroundGET /auth/me; router root guard redirects unauthenticated users to/login(preserving the intended destination) and bounces authenticated users away from/login//register.POST /auth/logout, then invalidate the me-query).Out of scope
Key files & patterns
web/src/lib/api.ts); zod-parse responses.Dependencies
Blocked by #2 and #4. The OIDC button lights up once #5 is deployed but must not require it (renders whatever
/auth/providersreports).Acceptance criteria
make dev): register → auto-login (or login) → redirected to/gardens; refresh keeps you in; logout returns to/login./gardens/1logged out redirects to/loginand returns you there after login.npx tsc --noEmitclean.