refactor: centralize validation, error handling, and formatting logic
Extract shared auth logic and validation rules to shared/auth.ts Introduce utility functions for HTTP errors and user input parsing Standardize error messages and date formatting across the app
This commit is contained in:
75
server/utils/users.ts
Normal file
75
server/utils/users.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import type { H3Event } from 'h3'
|
||||
|
||||
import {
|
||||
hasValidFullName,
|
||||
isUserRole,
|
||||
isValidPhoneNumber,
|
||||
isValidUsername,
|
||||
normalizeFullName,
|
||||
normalizePhoneNumber,
|
||||
normalizeUsername,
|
||||
type UserRole
|
||||
} from '~~/shared/auth'
|
||||
|
||||
import { assertBadRequest, getRequiredRouteParam, httpError } from './http'
|
||||
import { getUserById } from './user-repository'
|
||||
|
||||
export function requireUserIdParam(event: H3Event) {
|
||||
return getRequiredRouteParam(event, 'id', 'User id')
|
||||
}
|
||||
|
||||
export async function requireExistingUser(userId: string, statusMessage = 'User not found') {
|
||||
const user = await getUserById(userId)
|
||||
|
||||
if (!user) {
|
||||
httpError(404, statusMessage)
|
||||
}
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
export function parseCreateUserInput(body: {
|
||||
username?: string
|
||||
fullName?: string
|
||||
phoneNumber?: string
|
||||
role?: UserRole
|
||||
}) {
|
||||
const username = normalizeUsername(body.username || '')
|
||||
const fullName = normalizeFullName(body.fullName || '')
|
||||
const phoneNumber = normalizePhoneNumber(body.phoneNumber || '')
|
||||
const role = body.role === 'super_admin' ? 'super_admin' : 'staff'
|
||||
|
||||
assertBadRequest(
|
||||
isValidUsername(username),
|
||||
'Username must be 3 to 32 characters using lowercase letters, numbers, dot, dash, or underscore'
|
||||
)
|
||||
assertBadRequest(hasValidFullName(fullName), 'Full name must be at least 2 characters')
|
||||
assertBadRequest(isValidPhoneNumber(phoneNumber), 'Phone number must contain 8 to 15 digits')
|
||||
|
||||
return {
|
||||
username,
|
||||
fullName,
|
||||
phoneNumber,
|
||||
role
|
||||
}
|
||||
}
|
||||
|
||||
export function parseUserProfileInput(body: {
|
||||
fullName?: string
|
||||
phoneNumber?: string
|
||||
role?: UserRole
|
||||
}) {
|
||||
const fullName = normalizeFullName(body.fullName || '')
|
||||
const phoneNumber = normalizePhoneNumber(body.phoneNumber || '')
|
||||
const role = body.role
|
||||
|
||||
assertBadRequest(hasValidFullName(fullName), 'Display name must be at least 2 characters')
|
||||
assertBadRequest(isValidPhoneNumber(phoneNumber), 'Phone number must contain 8 to 15 digits')
|
||||
assertBadRequest(isUserRole(role), 'Role is invalid')
|
||||
|
||||
return {
|
||||
fullName,
|
||||
phoneNumber,
|
||||
role
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user