Files
budget/FILE_STORAGE.md
Nate Emmert 959249ab22 Migrate from Firebase to file-based storage system
- Remove Firebase dependency and all Firebase code
- Implement local file-based storage with encryption
- Create custom authentication system with password hashing
- Add API routes for auth (register/login) and data operations
- Create FileStorageService for server-side file I/O
- Add AuthService for client-side authentication wrapper
- Update all components to use new storage system
- Add comprehensive documentation (FILE_STORAGE.md, MIGRATION_SUMMARY.md)
- Improve security with AES-GCM encryption and SHA-256 password hashing
- Add ErrorBoundary component for better error handling
- Fix multiple bugs: date serialization, transaction deletion, envelope calculations
2025-11-08 14:03:26 -05:00

3.9 KiB

File-Based Storage System

This application uses a local file-based storage system instead of cloud databases like Firebase. All user data is stored on the server in JSON files.

Architecture

Storage Location

  • All user data is stored in the /data directory
  • User credentials: /data/users.json
  • User budget data: /data/{userId}.json

Authentication Flow

  1. User registers with email and password
  2. Password is hashed using SHA-256
  3. User credentials stored in /data/users.json
  4. Unique userId generated and returned to client
  5. Client stores userId in localStorage for session persistence

Data Storage Flow

  1. Client authenticates and receives userId
  2. Client makes API calls with userId in headers
  3. Server reads/writes user data file at /data/{userId}.json
  4. Data is encrypted server-side using AES-GCM encryption
  5. Encrypted data saved to disk

API Endpoints

Authentication

  • POST /api/auth/register - Register new user

    • Body: { email, password }
    • Returns: { userId, email }
  • POST /api/auth/login - Login existing user

    • Body: { email, password }
    • Returns: { userId, email }

Data Operations

  • GET /api/data - Load user data

    • Headers: x-user-id: {userId}
    • Returns: { data: UserData }
  • POST /api/data - Save user data

    • Headers: x-user-id: {userId}
    • Body: { accounts, envelopes, transactions, setupCompleted }
    • Returns: { success: true }

Security

Password Security

  • Passwords hashed with SHA-256 before storage
  • Original passwords never stored
  • Hash comparison done server-side

Data Encryption

  • All user budget data encrypted with AES-GCM
  • Encryption key stored in environment variable: ENCRYPTION_KEY
  • 256-bit encryption with PBKDF2 key derivation
  • Unique salt and IV for each encryption operation

Session Management

  • UserId stored in browser localStorage
  • No sensitive data in browser storage
  • Server validates userId on every request
  • User can sign out to clear session

Environment Variables

# .env.local
ENCRYPTION_KEY=your-32-byte-hex-key-here

Generate a secure key with:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

File Structure

/data
  ├── users.json              # User credentials (email → userId mapping)
  ├── {userId1}.json          # User 1 budget data (encrypted)
  ├── {userId2}.json          # User 2 budget data (encrypted)
  └── .gitignore              # Excludes all JSON files from git

Data Backup

Since all data is stored in local files:

  1. Regular Backups: Copy /data directory to secure backup location
  2. Version Control: The /data directory is gitignored for security
  3. Migration: Simply copy files to move data between servers
  4. Export: Users can export their data via the app's export feature

Development Setup

  1. Install dependencies:

    npm install
    
  2. Create .env.local:

    cp .env.local.example .env.local
    
  3. Generate encryption key:

    node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
    
  4. Update .env.local with your encryption key

  5. Start development server:

    npm run dev
    

Production Deployment

  1. Set environment variable ENCRYPTION_KEY on your server
  2. Ensure /data directory has write permissions
  3. Set up automated backups of /data directory
  4. Use HTTPS for all API communication
  5. Consider adding rate limiting to API routes
  6. Monitor /data directory disk usage

Migration from Firebase

The app previously used Firebase. The migration to file-based storage included:

  • ✅ Removed Firebase SDK dependency
  • ✅ Created custom authentication system
  • ✅ Implemented file-based data storage
  • ✅ Added encryption for data at rest
  • ✅ Created API routes for all operations
  • ✅ Updated all components to use new auth system

All Firebase code has been removed and replaced with local file storage.