3.5 KiB
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
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:
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
statefield is required (Better-Auth always emits it) so CSRF protection is enforced at the schema layer; callers that dropstatefail 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.