3.9 KiB
login
Purpose
Defines Zod schemas for the login request and response shapes used by Suaveplan's authentication endpoints. These schemas serve as the single source of truth consumed by the server route handler for POST /auth/login, the React login mutation hook, and the OpenAPI document generator — ensuring every layer shares the same field names, validation rules, and TypeScript types without duplication.
Features
LoginInputschema — validates{email, password}credentials with RFC 5322 email validationLoginUserembedded object schema — user identifier, email, display name, and roles array returned inside the login responseLoginOutputschema — wraps a short-lived accesstoken, a long-livedrefreshToken, and aLoginUserobject- All fields non-empty with appropriate Zod refinements
- Full TypeScript inference via
z.infer<>— no manual interface duplication - Zod v4 compatible
Usage: Basic Example
import { LoginInput, LoginOutput } from "@suaveplan/api-schemas/auth";
// Validate the parsed request body
const input = LoginInput.parse(req.body);
// → { email: "user@example.com", password: "secret" }
// Validate the response before serialising to JSON
const output = LoginOutput.parse({
token: "eyJhbGciOiJFZERTQSJ9...",
refreshToken: "rt_abc123",
user: { id: "user_01", email: "user@example.com", name: "Alice", roles: ["member"] },
});
Usage: Advanced Example
import { LoginInput, LoginOutput } from "@suaveplan/api-schemas/auth";
async function handleLogin(rawBody: unknown): Promise<LoginOutput> {
const { email, password } = LoginInput.parse(rawBody);
const user = await authService.verifyPassword(email, password);
const token = await tokenService.issueAccessToken(user.id);
const refreshToken = await tokenService.issueRefreshToken(user.id);
return LoginOutput.parse({ token, refreshToken, user });
}
API Reference
LoginInput
Zod object schema — login request body.
| Field | Type | Description |
|---|---|---|
email |
string (email) |
RFC 5322 valid email address |
password |
string (min 1) |
Plaintext password (TLS-only) |
Type export: type LoginInput = z.infer<typeof LoginInput>
LoginUser
Zod object schema — user payload embedded in the login response.
| Field | Type | Description |
|---|---|---|
id |
string (min 1) |
Unique user identifier |
email |
string (email) |
User email address |
name |
string (min 1) |
Display name |
roles |
string[] |
Array of role identifiers for this user |
Type export: type LoginUser = z.infer<typeof LoginUser>
LoginOutput
Zod object schema — login success response.
| Field | Type | Description |
|---|---|---|
token |
string (min 1) |
Short-lived access token |
refreshToken |
string (min 1) |
Long-lived refresh token |
user |
LoginUser |
Authenticated user details |
Type export: type LoginOutput = z.infer<typeof LoginOutput>
Implementation Notes
The password field uses z.string().min(1) rather than a minimum-length policy constraint because the schema layer validates wire format, not security policy. Minimum password length requirements belong in the registration flow and are enforced by the auth service. The access token format (JWT, opaque, etc.) is also not validated here — z.string().min(1) accepts any non-empty token string, keeping the schema decoupled from the token implementation.