From afd51571c57130ccb916d5e58bc3869ccc6b364d Mon Sep 17 00:00:00 2001 From: Bert Hausmans Date: Wed, 20 May 2026 22:44:08 +0200 Subject: [PATCH] feat(shared): add auth types and zod schemas --- packages/shared/src/schemas.ts | 65 ++++++++++++++++++++++++++++++++++ packages/shared/src/types.ts | 21 +++++++++++ 2 files changed, 86 insertions(+) diff --git a/packages/shared/src/schemas.ts b/packages/shared/src/schemas.ts index ab250dd..b0e86ed 100644 --- a/packages/shared/src/schemas.ts +++ b/packages/shared/src/schemas.ts @@ -43,3 +43,68 @@ export type CardCreateInput = z.infer; export type CardUpdateInput = z.infer; export type SessionStartInput = z.infer; export type AttemptCreateInput = z.infer; + +export const emailSchema = z.string().email().max(320).transform((v) => v.trim().toLowerCase()); + +export const registerSchema = z.object({ + email: emailSchema, + displayName: z.string().trim().min(1).max(120), + password: z.string().min(8).max(200), +}); + +export const loginSchema = z.object({ + email: emailSchema, + password: z.string().min(1).max(200), +}); + +export const forgotPasswordSchema = z.object({ email: emailSchema }); + +export const resetPasswordSchema = z.object({ + token: z.string().min(20).max(200), + password: z.string().min(8).max(200), +}); + +export const verifyEmailSchema = z.object({ + token: z.string().min(20).max(200), +}); + +export const resendVerificationSchema = z.object({ email: emailSchema }); + +export const profileUpdateSchema = z.object({ + displayName: z.string().trim().min(1).max(120).optional(), + email: emailSchema.optional(), +}); + +export const changePasswordSchema = z.object({ + currentPassword: z.string().min(1).max(200), + newPassword: z.string().min(8).max(200), +}); + +export const acceptInviteSchema = z.object({ + token: z.string().min(20).max(200), + displayName: z.string().trim().min(1).max(120), + password: z.string().min(8).max(200), +}); + +export const inviteUserSchema = z.object({ + email: emailSchema, + role: z.enum(['user', 'sysadmin']).default('user'), +}); + +export const adminUserUpdateSchema = z.object({ + displayName: z.string().trim().min(1).max(120).optional(), + role: z.enum(['user', 'sysadmin']).optional(), + isActive: z.boolean().optional(), +}); + +export type RegisterInput = z.infer; +export type LoginInput = z.infer; +export type ForgotPasswordInput = z.infer; +export type ResetPasswordInput = z.infer; +export type VerifyEmailInput = z.infer; +export type ResendVerificationInput = z.infer; +export type ProfileUpdateInput = z.infer; +export type ChangePasswordInput = z.infer; +export type AcceptInviteInput = z.infer; +export type InviteUserInput = z.infer; +export type AdminUserUpdateInput = z.infer; diff --git a/packages/shared/src/types.ts b/packages/shared/src/types.ts index 1cc1220..7a69219 100644 --- a/packages/shared/src/types.ts +++ b/packages/shared/src/types.ts @@ -71,3 +71,24 @@ export interface SessionSettings { shuffle: boolean; direction: 'forward' | 'backward' | 'both'; } + +export type Role = 'user' | 'sysadmin'; + +export interface User { + id: number; + email: string; + displayName: string; + role: Role; + isActive: boolean; + emailVerifiedAt: number | null; + pendingEmail: string | null; + createdAt: number; + updatedAt: number; +} + +export interface PublicUser { + id: number; + email: string; + displayName: string; + role: Role; +}