feat: POS PIN unlock with employee number + PIN auth
- Add employeeNumber and pinHash fields to users table - POST /auth/pin-login: takes combined code (4-digit employee# + 4-digit PIN) - POST /auth/set-pin: employee sets their own PIN (requires full auth) - DELETE /auth/pin: remove PIN - Lock screen with numpad, auto-submits on 8 digits, visual dot separator - POS uses its own auth token separate from admin session - Admin "POS" link clears admin session before navigating - /pos route has no auth guard — lock screen is the auth - API client uses POS token when available, admin token otherwise - Auto-lock timer reads pos_lock_timeout from app_config (default 15 min) - Lock button in POS top bar, shows current cashier name Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useAuthStore } from '@/stores/auth.store'
|
||||
import { usePOSStore } from '@/stores/pos.store'
|
||||
|
||||
class ApiError extends Error {
|
||||
statusCode: number
|
||||
@@ -13,7 +14,8 @@ class ApiError extends Error {
|
||||
}
|
||||
|
||||
async function request<T>(method: string, path: string, body?: unknown): Promise<T> {
|
||||
const { token } = useAuthStore.getState()
|
||||
// Use POS token if available (POS screen), otherwise admin token
|
||||
const token = usePOSStore.getState().token ?? useAuthStore.getState().token
|
||||
|
||||
const headers: Record<string, string> = {}
|
||||
|
||||
@@ -32,9 +34,12 @@ async function request<T>(method: string, path: string, body?: unknown): Promise
|
||||
})
|
||||
|
||||
if (res.status === 401) {
|
||||
useAuthStore.getState().logout()
|
||||
// Don't use window.location — that causes a full reload and flash
|
||||
// The router's beforeLoad guard will redirect to /login on next navigation
|
||||
// On POS, lock the screen instead of logging out admin
|
||||
if (usePOSStore.getState().token) {
|
||||
usePOSStore.getState().lock()
|
||||
} else {
|
||||
useAuthStore.getState().logout()
|
||||
}
|
||||
throw new ApiError('Unauthorized', 401)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user