05 — Auth & Tenancy
CEO Summary
Authentication and tenant resolution ensure the right user accesses the right business data. Every request must resolve to a tenant before any business logic runs. Business value: Security, compliance, data isolation. Key metrics: Login success rate, session duration. If this breaks: Users cannot log in; API returns 401; POS cannot operate.
Auth Flow
Platform Login
Route: POST /api/auth/login or POST /api/auth/oauth/login
File: backend/routes/auth.routes.js
- Validate email, password
- getTenantForEmployee(email) — tenant_employees (master)
- If tenant employee: query Users in tenant DB
- Else: query master Users
- bcrypt.compare(password, user.password)
- createUserSession — req.session.user, req.session.tenant
- Response: { success, user, tenant }
Session
Store: session-file-store or MySQL. Cookie: pawspos.sid, httpOnly, maxAge 24h. Path: ./sessions
Tenant Resolution Order
- Already resolved (req.tenant exists)
- Master admin (user.role === 'master_admin')
- Session tenantSlug
- Headers (X-Tenant-Slug, X-Org-Id)
- Session tenantId
- API key
- Subdomain
- Dev fallback
- Otherwise 401
Frontend Post-Login
AuthProvider receives { user, tenant } from GET /api/auth/status. setTenantContext → localStorage. All API calls send X-Tenant-Slug, X-Org-Id, X-Tenant-ID, Cookie.
POS Register Login
Route: POST /api/pos/register/authenticate. Requires: Platform session first. Validates Staff by email + PIN (bcrypt). Returns { success, staff } — no new session.
Middleware
| Middleware | Purpose |
|---|---|
| requireSessionAuth | Requires req.session.user. 401 otherwise. |
| optionalSessionAuth | Always next(). Does not block. |
| requireFlexibleAuth | Session OR API key. |
| deviceAuth | Device key for kiosk/mobile. |