69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
// JSON Schemas for auth payloads — the single source of truth. The backend
|
|
// validates requests against these (Fastify), and the payload TS types are
|
|
// derived from them via `FromSchema` (see ./types), so there is no drift.
|
|
|
|
import type { FromSchema } from 'json-schema-to-ts';
|
|
|
|
// Username: public handle, case-insensitive-unique. Letters/digits/underscore.
|
|
const USERNAME_PATTERN = '^[a-zA-Z0-9_]{3,32}$';
|
|
// E.164 phone, e.g. +14155552671.
|
|
const PHONE_PATTERN = '^\\+[1-9]\\d{1,14}$';
|
|
|
|
export const registerBodySchema = {
|
|
type: 'object',
|
|
additionalProperties: false,
|
|
required: ['username', 'displayName', 'password'],
|
|
properties: {
|
|
username: { type: 'string', pattern: USERNAME_PATTERN },
|
|
displayName: { type: 'string', minLength: 1, maxLength: 64 },
|
|
password: { type: 'string', minLength: 8, maxLength: 128 },
|
|
email: { type: 'string', format: 'email', maxLength: 254 },
|
|
phone: { type: 'string', pattern: PHONE_PATTERN },
|
|
},
|
|
} as const;
|
|
|
|
export const loginBodySchema = {
|
|
type: 'object',
|
|
additionalProperties: false,
|
|
required: ['username', 'password'],
|
|
properties: {
|
|
username: { type: 'string', pattern: USERNAME_PATTERN },
|
|
password: { type: 'string', minLength: 1, maxLength: 128 },
|
|
},
|
|
} as const;
|
|
|
|
export const refreshBodySchema = {
|
|
type: 'object',
|
|
additionalProperties: false,
|
|
required: ['refreshToken'],
|
|
properties: {
|
|
refreshToken: { type: 'string', minLength: 1 },
|
|
},
|
|
} as const;
|
|
|
|
export const logoutBodySchema = {
|
|
type: 'object',
|
|
additionalProperties: false,
|
|
required: ['refreshToken'],
|
|
properties: {
|
|
refreshToken: { type: 'string', minLength: 1 },
|
|
},
|
|
} as const;
|
|
|
|
export const updateMeBodySchema = {
|
|
type: 'object',
|
|
additionalProperties: false,
|
|
minProperties: 1,
|
|
properties: {
|
|
displayName: { type: 'string', minLength: 1, maxLength: 64 },
|
|
// `null` clears the value; a string sets it.
|
|
email: { type: ['string', 'null'], format: 'email', maxLength: 254 },
|
|
phone: { type: ['string', 'null'], pattern: PHONE_PATTERN },
|
|
},
|
|
} as const;
|
|
|
|
export type RegisterBody = FromSchema<typeof registerBodySchema>;
|
|
export type LoginBody = FromSchema<typeof loginBodySchema>;
|
|
export type RefreshBody = FromSchema<typeof refreshBodySchema>;
|
|
export type LogoutBody = FromSchema<typeof logoutBodySchema>;
|
|
export type UpdateMeBody = FromSchema<typeof updateMeBodySchema>;
|