# schemas/routes/oauth ## Purpose Schemas for the OAuth pair `GET /auth/oauth/:provider/start` and `GET /auth/oauth/:provider/callback`. The start endpoint initiates an OAuth flow (typically redirecting to the provider's authorization endpoint); the callback receives the provider's `code` + `state` and finishes the flow. ## Features - `OAuthStartParamsSchema` — `{ provider: string (min 1) }` for the path parameter. - `OAuthStartQuerySchema` — `{ redirectTo?: string (url) }` so callers can request a specific post-login redirect. - `OAuthStartResponseSchema` — `{ redirectTo: string (url) }`; the body shape used when the response is a 200 + JSON pointer rather than a direct 302. - `OAuthCallbackParamsSchema` + `OAuthCallbackQuerySchema` — `{ code, state }` from the provider. - `OAuthCallbackResponseSchema` — `{ redirectTo: string (url) }` for the same 200 + JSON pointer variant. ## Usage: Basic ```ts import { OAuthStartQuerySchema, OAuthCallbackQuerySchema } from "@suaveplan/api-plugin-auth/schemas/routes"; const startQuery = OAuthStartQuerySchema.parse({ redirectTo: "https://example.test/" }); const callbackQuery = OAuthCallbackQuerySchema.parse({ code: "abc", state: "xyz" }); ``` ## Usage: Advanced Use the params + query + response shapes inside a `RouteBuilder` chain so the OpenAPI doc advertises a fully-typed OAuth flow including the required `state` field on the callback: ```ts import { GET, successResponse } from "@suaveplan/api-openapi"; import { OAuthCallbackParamsSchema, OAuthCallbackQuerySchema, OAuthCallbackResponseSchema, OAuthStartParamsSchema, OAuthStartQuerySchema, OAuthStartResponseSchema, } from "@suaveplan/api-plugin-auth/schemas/routes"; const startRoute = GET("/auth/oauth/{provider}/start") .tags("auth", "oauth") .summary("Begin OAuth flow with the named provider") .params(OAuthStartParamsSchema) .query(OAuthStartQuerySchema) .response(successResponse(OAuthStartResponseSchema)) .build(); const callbackRoute = GET("/auth/oauth/{provider}/callback") .tags("auth", "oauth") .summary("OAuth callback — exchange code for session") .params(OAuthCallbackParamsSchema) .query(OAuthCallbackQuerySchema) .response(successResponse(OAuthCallbackResponseSchema)) .build(); ``` ## API Reference ### `OAuthStartParamsSchema` `{ provider: string (min 1) }`. Inferred type `OAuthStartParams`. ### `OAuthStartQuerySchema` `{ redirectTo?: string (url) }`. Inferred type `OAuthStartQuery`. ### `OAuthStartResponseSchema` `{ redirectTo: string (url) }`. ### `OAuthCallbackParamsSchema` `{ provider: string (min 1) }`. Inferred type `OAuthCallbackParams`. ### `OAuthCallbackQuerySchema` `{ code: string (min 1); state: string (min 1) }`. Inferred type `OAuthCallbackQuery`. ### `OAuthCallbackResponseSchema` `{ redirectTo: string (url) }`. ## Implementation Notes - The OAuth pair is documented as 200-with-JSON-redirect in OpenAPI for ergonomics — Better-Auth's runtime handler may return a 302 directly, which is compatible with the OpenAPI doc because consumers reading the spec see the "redirectTo" pointer either way. - The callback's `state` field is required (Better-Auth always emits it) so CSRF protection is enforced at the schema layer; callers that drop `state` fail Zod validation before Better-Auth ever runs. - Provider validation is structural — the route accepts any provider string; Better-Auth's configured providers map decides whether the call succeeds at runtime.