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:
@@ -176,7 +176,14 @@ function AuthenticatedLayout() {
|
||||
<div className="flex-1 overflow-y-auto px-2 space-y-1 scrollbar-thin">
|
||||
{isModuleEnabled('pos') && canViewPOS && (
|
||||
<div className="mb-2">
|
||||
<NavLink to="/pos" icon={<ShoppingCart className="h-4 w-4" />} label="Point of Sale" collapsed={collapsed} />
|
||||
<button
|
||||
onClick={() => { logout(); router.navigate({ to: '/pos' }) }}
|
||||
className="flex items-center gap-2 px-3 py-2 rounded-md text-sm text-sidebar-foreground hover:bg-sidebar-accent w-full"
|
||||
title={collapsed ? 'Point of Sale' : undefined}
|
||||
>
|
||||
<ShoppingCart className="h-4 w-4" />
|
||||
{!collapsed && 'Point of Sale'}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{canViewAccounts && (
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
import { createFileRoute, redirect } from '@tanstack/react-router'
|
||||
import { useAuthStore } from '@/stores/auth.store'
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
import { POSRegister } from '@/components/pos/pos-register'
|
||||
|
||||
export const Route = createFileRoute('/pos')({
|
||||
beforeLoad: () => {
|
||||
const { token } = useAuthStore.getState()
|
||||
if (!token) {
|
||||
throw redirect({ to: '/login' })
|
||||
}
|
||||
},
|
||||
component: POSPage,
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user