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
76 lines
2.0 KiB
TypeScript
76 lines
2.0 KiB
TypeScript
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
|
|
}
|
|
}
|