05 — Auth & Tenancy

Login, session, tenant resolution

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

sequenceDiagram participant User participant Login participant AuthRoutes participant TenantRouting participant MasterDB participant TenantDB User->>Login: email + password Login->>AuthRoutes: POST /api/auth/login AuthRoutes->>TenantRouting: getTenantForEmployee(email) TenantRouting->>MasterDB: tenant_employees alt Tenant employee AuthRoutes->>TenantDB: Query Users else Platform user AuthRoutes->>MasterDB: Query Users end AuthRoutes->>AuthRoutes: bcrypt.compare AuthRoutes->>AuthRoutes: createUserSession AuthRoutes-->>User: { user, tenant }

Platform Login

Route: POST /api/auth/login or POST /api/auth/oauth/login

File: backend/routes/auth.routes.js

  1. Validate email, password
  2. getTenantForEmployee(email) — tenant_employees (master)
  3. If tenant employee: query Users in tenant DB
  4. Else: query master Users
  5. bcrypt.compare(password, user.password)
  6. createUserSession — req.session.user, req.session.tenant
  7. Response: { success, user, tenant }

Session

Store: session-file-store or MySQL. Cookie: pawspos.sid, httpOnly, maxAge 24h. Path: ./sessions

Tenant Resolution Order

  1. Already resolved (req.tenant exists)
  2. Master admin (user.role === 'master_admin')
  3. Session tenantSlug
  4. Headers (X-Tenant-Slug, X-Org-Id)
  5. Session tenantId
  6. API key
  7. Subdomain
  8. Dev fallback
  9. 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

MiddlewarePurpose
requireSessionAuthRequires req.session.user. 401 otherwise.
optionalSessionAuthAlways next(). Does not block.
requireFlexibleAuthSession OR API key.
deviceAuthDevice key for kiosk/mobile.