Files
skills/docs/api-stack/api/api-plugin-auth/src/schemas/routes/oauth.md
2026-05-29 08:20:56 +01:00

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 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.