5.7 KiB
Security Migration: Frontend to Cloud Functions
Overview
This migration addresses critical security vulnerabilities by moving all Firestore interactions from the frontend to secure cloud functions. This prevents unauthorized data access and protects your database structure from being exposed to users.
Security Issues Addressed
Before (Vulnerable)
- ❌ Direct Firestore access from frontend
- ❌ Database schema exposed to users
- ❌ API keys visible in browser
- ❌ Firestore rules can be analyzed by attackers
- ❌ Users can potentially bypass frontend logic
After (Secure)
- ✅ All data operations go through authenticated cloud functions
- ✅ Database structure hidden from frontend
- ✅ User authorization verified on every request
- ✅ No sensitive data exposed to client
- ✅ Complete audit trail of data access
Migration Changes
1. Cloud Functions (Backend)
File: functions/index.js
Added secure endpoints:
getOrgData- Get organization data with authupdateOrgData- Update organization data with authgetEmployees- Get employees with authgetSubmissions- Get submissions with authgetReports- Get reports with authupsertEmployee- Create/update employees with authsaveReport- Save reports with authgetCompanyReports- Get company reports with auth
Each endpoint:
- Verifies user authentication
- Checks user authorization for the organization
- Validates all inputs
- Returns appropriate error messages
2. Secure API Service (Frontend)
File: src/services/secureApi.ts
New service that:
- Handles all communication with cloud functions
- Provides type-safe methods for data operations
- Manages authentication tokens
- Handles errors gracefully
3. Updated Context (Frontend)
File: src/contexts/OrgContext.tsx
Completely rewritten to:
- Use secure API instead of direct Firestore
- Load data on component mount instead of real-time listeners
- Provide loading states for better UX
- Handle authentication properly
4. Firestore Rules (Security)
File: firestore.rules
Updated rules to:
// DENY ALL direct client access
allow read, write: if false;
Deployment Steps
-
Deploy Cloud Functions
cd functions npm install cd .. firebase deploy --only functions -
Deploy Firestore Rules
firebase deploy --only firestore:rules -
Use Deployment Script
./deploy-security.sh
Frontend Usage
Before (Direct Firestore)
// DON'T DO THIS ANYMORE
import { collection, doc, getDoc } from 'firebase/firestore';
const orgDoc = await getDoc(doc(db, 'orgs', orgId));
After (Secure API)
// DO THIS INSTEAD
import { secureApi } from '../services/secureApi';
const orgData = await secureApi.getOrgData(orgId, userId);
API Methods Available
Organization Data
secureApi.getOrgData(orgId, userId)secureApi.updateOrgData(orgId, userId, data)
Employees
secureApi.getEmployees(orgId, userId)secureApi.upsertEmployee(orgId, userId, employeeData)
Submissions & Reports
secureApi.getSubmissions(orgId, userId)secureApi.getReports(orgId, userId)secureApi.saveReport(orgId, userId, employeeId, reportData)
Company Reports
secureApi.getCompanyReports(orgId, userId)secureApi.saveCompanyReport(orgId, report)
Existing API (Already Secure)
secureApi.sendOTP(email, inviteCode?)secureApi.verifyOTP(email, otp)secureApi.createInvitation(...)secureApi.generateEmployeeReport(...)secureApi.generateCompanyWiki(...)secureApi.chat(...)
Authentication Flow
- User logs in via OTP (cloud function)
- Cloud function returns user data and token
- Frontend stores user data in AuthContext
- All API calls include user ID for authorization
- Cloud functions verify user access to organization data
Error Handling
The secure API provides consistent error handling:
try {
const data = await secureApi.getOrgData(orgId, userId);
// Handle success
} catch (error) {
// Handle error - could be auth, network, or data error
console.error('Failed to load organization:', error.message);
}
Performance Considerations
- Loading States: UI shows loading while data fetches
- Caching: Local state caching reduces API calls
- Batch Operations: Multiple related operations in single calls
- Error Recovery: Graceful fallbacks for network issues
Security Benefits
- Zero Trust: Every request is authenticated and authorized
- Data Hiding: Database schema not exposed to frontend
- Audit Trail: All access logged in cloud functions
- Input Validation: All data validated server-side
- Rate Limiting: Can be added to cloud functions
- IP Filtering: Can be implemented at cloud function level
Testing
After migration, verify:
- ✅ Users can only access their organization's data
- ✅ Unauthenticated requests are rejected
- ✅ Invalid organization IDs are rejected
- ✅ All CRUD operations work through secure API
- ✅ Error messages don't leak sensitive information
Monitoring
Monitor these metrics:
- API response times
- Authentication failures
- Authorization failures
- Data access patterns
- Error rates
Future Enhancements
This secure foundation enables:
- Role-based access control (RBAC)
- Data encryption at rest
- Advanced audit logging
- API rate limiting
- IP whitelisting
- Multi-factor authentication
Support
If you encounter issues:
- Check browser console for detailed error messages
- Verify Firebase project configuration
- Ensure cloud functions are deployed successfully
- Check Firestore rules are updated
The secure API provides comprehensive error messages to help debug issues during development.