feat: implement auth system, passkeys, and user management
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
This commit is contained in:
57
shared/auth.ts
Normal file
57
shared/auth.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user