Stage M2
This commit is contained in:
@@ -28,5 +28,12 @@ export const registerSchema = z.object({
|
||||
acceptsMarketing: z.boolean().default(false),
|
||||
});
|
||||
|
||||
/**
|
||||
* The refresh token travels as an httpOnly cookie, never in a body — so this
|
||||
* schema is deliberately empty. It exists to document that the endpoint takes
|
||||
* no client-supplied input, which is what makes it safe to expose unauthenticated.
|
||||
*/
|
||||
export const refreshSchema = z.object({});
|
||||
|
||||
export type LoginInput = z.infer<typeof loginSchema>;
|
||||
export type RegisterInput = z.infer<typeof registerSchema>;
|
||||
|
||||
@@ -15,3 +15,4 @@ export * from './common';
|
||||
export * from './pagination';
|
||||
export * from './auth';
|
||||
export * from './catalog';
|
||||
export * from './users';
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { passwordSchema } from './auth';
|
||||
import { anyIdSchema, emailSchema, phoneSchema } from './common';
|
||||
import { offsetPageQuerySchema } from './pagination';
|
||||
|
||||
/**
|
||||
* Back-office user and role management.
|
||||
*
|
||||
* Note what is *not* here: no `permissions` array on a user. Permissions are
|
||||
* granted only through roles (ADR-0007). Allowing per-user overrides would make
|
||||
* "who can refund an order?" unanswerable without inspecting every account.
|
||||
*/
|
||||
|
||||
export const userTypeSchema = z.enum(['CUSTOMER', 'STAFF', 'ADMIN', 'SUPER_ADMIN']);
|
||||
export const userStatusSchema = z.enum(['ACTIVE', 'INVITED', 'SUSPENDED']);
|
||||
|
||||
/** Back-office accounts only — customers are created by registration. */
|
||||
export const backOfficeUserTypeSchema = z.enum(['STAFF', 'ADMIN', 'SUPER_ADMIN']);
|
||||
|
||||
export const userListQuerySchema = offsetPageQuerySchema.extend({
|
||||
q: z.string().trim().max(120).optional(),
|
||||
type: userTypeSchema.optional(),
|
||||
status: userStatusSchema.optional(),
|
||||
});
|
||||
|
||||
export const createUserSchema = z.object({
|
||||
email: emailSchema,
|
||||
password: passwordSchema,
|
||||
firstName: z.string().trim().min(1).max(80),
|
||||
lastName: z.string().trim().min(1).max(80),
|
||||
phone: phoneSchema.optional(),
|
||||
type: backOfficeUserTypeSchema,
|
||||
roleIds: z.array(anyIdSchema).default([]),
|
||||
});
|
||||
|
||||
export const updateUserSchema = z.object({
|
||||
firstName: z.string().trim().min(1).max(80).optional(),
|
||||
lastName: z.string().trim().min(1).max(80).optional(),
|
||||
phone: phoneSchema.nullish(),
|
||||
status: userStatusSchema.optional(),
|
||||
type: backOfficeUserTypeSchema.optional(),
|
||||
roleIds: z.array(anyIdSchema).optional(),
|
||||
});
|
||||
|
||||
/** An operator resetting someone else's password — no current password needed. */
|
||||
export const resetUserPasswordSchema = z.object({
|
||||
password: passwordSchema,
|
||||
});
|
||||
|
||||
/** A user changing their own password — proves possession of the current one. */
|
||||
export const changePasswordSchema = z.object({
|
||||
currentPassword: z.string().min(1),
|
||||
newPassword: passwordSchema,
|
||||
});
|
||||
|
||||
export const roleKeySchema = z
|
||||
.string()
|
||||
.trim()
|
||||
.min(2)
|
||||
.max(64)
|
||||
.regex(/^[a-z][a-z0-9_]*$/, 'Use lowercase letters, digits and underscores');
|
||||
|
||||
export const createRoleSchema = z.object({
|
||||
key: roleKeySchema,
|
||||
name: z.string().trim().min(2).max(120),
|
||||
description: z.string().trim().max(500).nullish(),
|
||||
permissions: z.array(z.string().max(64)).default([]),
|
||||
});
|
||||
|
||||
export const updateRoleSchema = z.object({
|
||||
name: z.string().trim().min(2).max(120).optional(),
|
||||
description: z.string().trim().max(500).nullish(),
|
||||
permissions: z.array(z.string().max(64)).optional(),
|
||||
});
|
||||
|
||||
export type UserListQuery = z.output<typeof userListQuerySchema>;
|
||||
export type CreateUserInput = z.output<typeof createUserSchema>;
|
||||
export type UpdateUserInput = z.output<typeof updateUserSchema>;
|
||||
export type CreateRoleInput = z.output<typeof createRoleSchema>;
|
||||
export type UpdateRoleInput = z.output<typeof updateRoleSchema>;
|
||||
export type ChangePasswordInput = z.output<typeof changePasswordSchema>;
|
||||
Reference in New Issue
Block a user