Users & Authentication
The auth system handles user authentication across all SMACKZ applications. It uses Firebase for identity management with different auth modes for different client types.
Auth Modes
| Client | Auth Method | Firebase Mode |
|---|---|---|
| Mobile (customers) | Phone OTP | Project-level Phone Auth (no tenants) |
| Admin (owners/admins) | Email/Password | Identity Platform (tenants) |
| SuperAdmin | Email/Password | Platform Firebase (always) |
Mobile Auth Flow
Phone Login Screen
|
| signInWithPhoneNumber(phone)
v
Firebase sends OTP via SMS
|
v
OTP Screen (enter 6-digit code)
|
| confirm(verificationId, code)
v
POST /auth/login/mobile/:restaurantId
|
+---> Existing user: return user + session
+---> New user: signal "complete registration"
|
v
Register Screen (name, email)
|
v
POST /auth/register/:restaurantId
Test phone numbers bypass SMS but follow the exact same flow -- no separate code paths.
Admin Auth Flow
GET /auth/firebase-config?email=user@example.com
|
| Returns firebaseApiKey + projectId
v
Client initializes Firebase SDK with received config
|
| signInWithEmailAndPassword
v
POST /auth/admin/login
Headers: authorization, device_id, login_source: web
|
v
Backend verifies token, returns session
SuperAdmin Authentication
SuperAdmin users always authenticate against platform Firebase, regardless of which restaurant they are managing. The critical rule:
login_source: webheader causes the backend to always use platform Firebase for token verification- SuperAdmin can include
x-restaurant-idfor context without affecting authentication - Authorization is role-based (
SuperAdminrole bypasses restaurant ID matching)
User Roles
| Role | Scope | Description |
|---|---|---|
SuperAdmin |
Platform-wide | Full access to all restaurants |
RestaurantOwner |
Per restaurant | Manages their own restaurant |
RestaurantManager |
Per restaurant | Day-to-day operations |
RestaurantUser |
Per restaurant | Limited staff access |
Customer |
Per restaurant | End consumers |
Multi-Restaurant Support
A single phone number can be registered with multiple restaurants. The backend uses base62-encoded Firebase custom claims (m claim) to track restaurant memberships. This keeps the claim compact enough to fit within Firebase's token size limits.
Token Lifecycle
| Token | Lifetime | Storage |
|---|---|---|
| Firebase ID Token | ~1 hour | Secure Store (mobile), Redux (admin) |
| Firebase Refresh Token | Long-lived | Secure Store (mobile), Redux (admin) |
On 401 responses, clients refresh the token via POST /auth/refresh and retry the original request. If refresh fails, the user is logged out.
Key API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/auth/firebase-config |
GET | Get Firebase config for a restaurant or email |
/auth/login/mobile/:restaurantId |
POST | Mobile phone login |
/auth/admin/login |
POST | Admin email login |
/auth/register/:restaurantId |
POST | New user registration |
/auth/refresh |
POST | Token refresh |
Key Files
docs/Auth-System.md-- Cross-project auth overviewyum/api/decorators/firebaseAuth.ts-- Firebase token verificationyum/api/firebaseAdmin/index.ts-- Firebase project selection logicyum/docs/AUTHENTICATION.md-- Backend auth documentationyum/docs/MULTI_TENANCY_ARCHITECTURE.md-- Multi-tenant Firebase architecture