Add PostgreSQL and Redis integration for users and sessions Implement password and WebAuthn passkey login flows Add Docker stack, super-admin seeding, and protected routes
58 lines
1.2 KiB
TypeScript
58 lines
1.2 KiB
TypeScript
export const DEFAULT_USER_PASSWORD = '123456'
|
|
export const MIN_PASSWORD_LENGTH = 8
|
|
export const USERNAME_PATTERN = /^[a-z0-9._-]{3,32}$/
|
|
export const PHONE_NUMBER_PATTERN = /^\+?\d{8,15}$/
|
|
|
|
export type UserRole = 'super_admin' | 'staff'
|
|
|
|
export function normalizePhoneNumber(value: string) {
|
|
const trimmed = value.trim()
|
|
|
|
if (!trimmed) {
|
|
return ''
|
|
}
|
|
|
|
const hasPlusPrefix = trimmed.startsWith('+')
|
|
const digitsOnly = trimmed.replace(/\D/g, '')
|
|
|
|
return hasPlusPrefix ? `+${digitsOnly}` : digitsOnly
|
|
}
|
|
|
|
export function isValidPhoneNumber(value: string) {
|
|
return PHONE_NUMBER_PATTERN.test(normalizePhoneNumber(value))
|
|
}
|
|
|
|
export interface AuthUser {
|
|
id: string
|
|
username: string
|
|
fullName: string
|
|
phoneNumber: string | null
|
|
role: UserRole
|
|
isActive: boolean
|
|
mustChangePassword: boolean
|
|
needsPasskeySetup: boolean
|
|
passkeyCount: number
|
|
createdAt: string
|
|
lastLoginAt: string | null
|
|
}
|
|
|
|
export interface ManagedUser extends AuthUser {
|
|
createdBy: string | null
|
|
}
|
|
|
|
export interface PublicContact {
|
|
id: string
|
|
fullName: string
|
|
phoneNumber: string
|
|
role: UserRole
|
|
}
|
|
|
|
export interface PasskeySummary {
|
|
id: string
|
|
label: string
|
|
createdAt: string
|
|
lastUsedAt: string | null
|
|
deviceType: 'singleDevice' | 'multiDevice'
|
|
backedUp: boolean
|
|
}
|