Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
# 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
- `LoginInput` schema — validates `{email, password}` credentials with RFC 5322 email validation
- `LoginUser` embedded object schema — user identifier, email, display name, and roles array returned inside the login response
- `LoginOutput` schema — wraps a short-lived access `token`, a long-lived `refreshToken`, and a `LoginUser` object
- All fields non-empty with appropriate Zod refinements
- Full TypeScript inference via `z.infer<>` — no manual interface duplication
- Zod v4 compatible
## Usage: Basic Example
```ts
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
```ts
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.