- api: auth controller/service, config env - web: App/LoginPage/ProfilePage, garde d'auth, client API, styles - shared: types/contrats auth - compose: variables d'environnement first-run Refs: #14
140 lines
4.3 KiB
TypeScript
140 lines
4.3 KiB
TypeScript
import { z } from "zod";
|
|
|
|
export const RoleSchema = z.enum(["admin", "user"]);
|
|
export type Role = z.infer<typeof RoleSchema>;
|
|
|
|
export const UserSchema = z.object({
|
|
id: z.number().int().positive(),
|
|
email: z.string().email(),
|
|
name: z.string().nullable(),
|
|
role: RoleSchema,
|
|
createdAt: z.string()
|
|
});
|
|
export type UserDto = z.infer<typeof UserSchema>;
|
|
|
|
export const BootstrapAdminSchema = z.object({
|
|
email: z.string().email(),
|
|
password: z.string().min(8),
|
|
name: z.string().min(1).max(120).optional()
|
|
});
|
|
export type BootstrapAdminDto = z.infer<typeof BootstrapAdminSchema>;
|
|
|
|
export const LoginSchema = z.object({
|
|
email: z.string().email(),
|
|
password: z.string().min(1)
|
|
});
|
|
export type LoginDto = z.infer<typeof LoginSchema>;
|
|
|
|
export const AuthStatusSchema = z.object({
|
|
hasUsers: z.boolean(),
|
|
initialAdminEmail: z.string().email(),
|
|
initialAdminPasswordIsDefault: z.boolean()
|
|
});
|
|
export type AuthStatusDto = z.infer<typeof AuthStatusSchema>;
|
|
|
|
export const UpdateAccountSchema = z
|
|
.object({
|
|
email: z.string().email().optional(),
|
|
name: z.string().min(1).max(120).nullable().optional(),
|
|
currentPassword: z.string().min(1),
|
|
newPassword: z.string().min(8).optional()
|
|
})
|
|
.refine((value) => value.email !== undefined || value.name !== undefined || value.newPassword !== undefined, {
|
|
message: "At least one account field must be changed"
|
|
});
|
|
export type UpdateAccountDto = z.infer<typeof UpdateAccountSchema>;
|
|
|
|
export const CreateUserSchema = z.object({
|
|
email: z.string().email(),
|
|
password: z.string().min(8),
|
|
name: z.string().min(1).max(120).optional(),
|
|
role: RoleSchema.default("user")
|
|
});
|
|
export type CreateUserDto = z.infer<typeof CreateUserSchema>;
|
|
|
|
export const UpdateUserSchema = z.object({
|
|
email: z.string().email().optional(),
|
|
password: z.string().min(8).optional(),
|
|
name: z.string().min(1).max(120).nullable().optional(),
|
|
role: RoleSchema.optional()
|
|
});
|
|
export type UpdateUserDto = z.infer<typeof UpdateUserSchema>;
|
|
|
|
export const LibrarySchema = z.object({
|
|
id: z.number().int().positive(),
|
|
name: z.string(),
|
|
path: z.string(),
|
|
enabled: z.boolean(),
|
|
createdAt: z.string(),
|
|
updatedAt: z.string()
|
|
});
|
|
export type LibraryDto = z.infer<typeof LibrarySchema>;
|
|
|
|
export const CreateLibrarySchema = z.object({
|
|
name: z.string().min(1).max(160),
|
|
path: z.string().min(1),
|
|
enabled: z.boolean().default(true)
|
|
});
|
|
export type CreateLibraryDto = z.infer<typeof CreateLibrarySchema>;
|
|
|
|
export const UpdateLibrarySchema = z.object({
|
|
name: z.string().min(1).max(160).optional(),
|
|
path: z.string().min(1).optional(),
|
|
enabled: z.boolean().optional()
|
|
});
|
|
export type UpdateLibraryDto = z.infer<typeof UpdateLibrarySchema>;
|
|
|
|
export const BookSchema = z.object({
|
|
id: z.number().int().positive(),
|
|
libraryId: z.number().int().positive(),
|
|
title: z.string(),
|
|
author: z.string().nullable(),
|
|
description: z.string().nullable(),
|
|
isbn: z.string().nullable(),
|
|
language: z.string().nullable(),
|
|
publisher: z.string().nullable(),
|
|
publishedDate: z.string().nullable(),
|
|
format: z.enum(["epub", "pdf"]),
|
|
filePath: z.string(),
|
|
coverPath: z.string().nullable(),
|
|
fileSize: z.number().int().nonnegative(),
|
|
fileMtime: z.string(),
|
|
createdAt: z.string(),
|
|
updatedAt: z.string()
|
|
});
|
|
export type BookDto = z.infer<typeof BookSchema>;
|
|
|
|
export const BookQuerySchema = z.object({
|
|
q: z.string().optional(),
|
|
format: z.enum(["epub", "pdf"]).optional(),
|
|
libraryId: z.coerce.number().int().positive().optional(),
|
|
limit: z.coerce.number().int().min(1).max(100).default(50),
|
|
offset: z.coerce.number().int().min(0).default(0)
|
|
});
|
|
export type BookQueryDto = z.infer<typeof BookQuerySchema>;
|
|
|
|
export const ProgressSchema = z.object({
|
|
bookId: z.number().int().positive(),
|
|
locator: z.string().min(1),
|
|
percent: z.number().min(0).max(100),
|
|
updatedAt: z.string()
|
|
});
|
|
export type ProgressDto = z.infer<typeof ProgressSchema>;
|
|
|
|
export const UpdateProgressSchema = z.object({
|
|
locator: z.string().min(1),
|
|
percent: z.number().min(0).max(100)
|
|
});
|
|
export type UpdateProgressDto = z.infer<typeof UpdateProgressSchema>;
|
|
|
|
export const JobSchema = z.object({
|
|
id: z.number().int().positive(),
|
|
type: z.string(),
|
|
status: z.enum(["queued", "running", "succeeded", "failed"]),
|
|
detail: z.string().nullable(),
|
|
error: z.string().nullable(),
|
|
createdAt: z.string(),
|
|
updatedAt: z.string()
|
|
});
|
|
export type JobDto = z.infer<typeof JobSchema>;
|