3.1 KiB
refresh
Purpose
Defines Zod schemas for the token-refresh request and response shapes used by Suaveplan's POST /auth/refresh endpoint. The refresh flow implements token rotation — each use of a refresh token returns both a new access token and a new refresh token, invalidating the consumed one. These schemas are shared between the server route handler, the React auth hook that silently re-authenticates expiring sessions, and the OpenAPI generator.
Features
RefreshInputschema — accepts a singlerefreshTokenstring (non-empty)RefreshOutputschema — returns a newtoken(access) and newrefreshToken(rotation pattern)- Non-empty validation on both token fields to prevent silent empty-string bypasses
- Full TypeScript inference via
z.infer<>— no manual interface duplication - Zod v4 compatible
Usage: Basic Example
import { RefreshInput, RefreshOutput } from "@suaveplan/api-schemas/auth";
// Validate the request body
const input = RefreshInput.parse(req.body);
// → { refreshToken: "rt_abc123..." }
// Validate the response
const output = RefreshOutput.parse({ token: "new-access-token", refreshToken: "new-rt_xyz" });
Usage: Advanced Example
import { RefreshInput, RefreshOutput } from "@suaveplan/api-schemas/auth";
async function handleRefresh(rawBody: unknown): Promise<RefreshOutput> {
const { refreshToken } = RefreshInput.parse(rawBody);
const session = await sessionStore.consume(refreshToken); // invalidates old token
const newAccess = await tokenService.issueAccessToken(session.userId);
const newRefresh = await sessionStore.issue(session.userId);
return RefreshOutput.parse({ token: newAccess, refreshToken: newRefresh });
}
API Reference
RefreshInput
Zod object schema — token refresh request body.
| Field | Type | Description |
|---|---|---|
refreshToken |
string (min 1) |
Long-lived refresh token from a prior login/refresh |
Type export: type RefreshInput = z.infer<typeof RefreshInput>
RefreshOutput
Zod object schema — token refresh success response.
| Field | Type | Description |
|---|---|---|
token |
string (min 1) |
New short-lived access token |
refreshToken |
string (min 1) |
New long-lived refresh token (rotation) |
Type export: type RefreshOutput = z.infer<typeof RefreshOutput>
Implementation Notes
The output deliberately echoes the same shape as LoginOutput's token fields, allowing React hooks to handle both login and refresh responses through a shared token-update function. Token rotation (issuing a new refresh token each time) is recommended by OAuth 2.0 Security Best Practices to limit the damage from a stolen refresh token. The server should record and compare the previous refresh token before issuing the new pair, rejecting any reuse attempts.