Skip to content

User Signup Flow

This document outlines the user signup flow for OmniButler.

System Flow

```mermaid sequenceDiagram participant User participant Frontend participant Firebase Auth participant Backend participant Firestore participant Turso

User->>Frontend: Sign in with Google
Frontend->>Firebase Auth: Authenticate
Firebase Auth-->>Frontend: Return Firebase Token
Frontend->>Backend: Request API Access (with token)
Backend->>Firebase Auth: Verify Token
Firebase Auth-->>Backend: Token Verified
Backend->>Firestore: Check for Existing User
alt User Exists
    Firestore-->>Backend: Return Existing User
else New User
    Backend->>Turso: Create User Database
    Turso-->>Backend: Database Created
    Backend->>Firestore: Create New User Record
    Firestore-->>Backend: User Created
end
Backend-->>Frontend: Return User Data

```

Implementation Details

Once a user signs up through the Google OAuth flow, we:

  1. Authenticate with Firebase
  2. Create a database instance for the user
  3. Store user metadata in Firestore
  4. Configure default settings
  5. Return the user profile

Code Flow

```mermaid graph TD subgraph Frontend A[User Sign In] → B[Firebase Auth SDK] B → C[Get Firebase Token] end

subgraph Backend
    D[API Request with Token] --> E[Auth Middleware]
    E --> F[verify_firebase_token]

    subgraph Application Layer
        F --> G[FirestoreAppUserRepository]
        G --> H[find_by_provider_user_id]
    end

    subgraph Domain Layer
        H --> I[AppUser Model]
        I --> J[DatabaseInfo Model]
    end

    subgraph Infrastructure Layer
        J --> K[TursoAdminClient]
        K --> L[create_database]
        K --> M[create_database_token]
        G --> N[Firestore Operations]
    end
end

style Frontend fill:#f9f,stroke:#333,stroke-width:2px
style Backend fill:#bbf,stroke:#333,stroke-width:2px
style Application Layer fill:#dfd,stroke:#333,stroke-width:2px
style Domain Layer fill:#fdd,stroke:#333,stroke-width:2px
style Infrastructure Layer fill:#ddf,stroke:#333,stroke-width:2px

```

Key Components

  1. Frontend
  2. Firebase Auth SDK
  3. Token management
  4. API client

  5. Application Layer

  6. FirestoreAppUserRepository: Manages user data persistence
  7. verify_firebase_token: Handles token verification
  8. API routes and controllers

  9. Domain Layer

  10. AppUser: Core user entity
  11. DatabaseInfo: Database connection details
  12. ProviderUser: External provider user data

  13. Infrastructure Layer

  14. TursoAdminClient: Database management
  15. Firestore client
  16. Firebase admin SDK

Technical Details

Authentication Flow

  1. Initial Authentication
  2. User signs in through Google OAuth
  3. Firebase Authentication generates a JWT token
  4. Token includes user details (name, email, provider ID)

  5. Token Verification

  6. Backend verifies the Firebase token
  7. Extracts user information:

    • uid: Firebase user ID
    • email: User's email address
    • name: User's display name
    • provider_name: Authentication provider (e.g., "google.com")
  8. User Creation/Retrieval

  9. System checks for existing user using provider ID
  10. If new user:
    • Creates unique appUserId
    • Initializes user database in Turso
    • Creates Firestore user record
  11. If existing user:
    • Retrieves user data
    • Updates provider information if needed

Data Models

AppUser

interface AppUser {
    appUserId: string;
    names: string[];
    providerUserIds: {
        [provider: string]: string[];
    };
    database_info?: {
        access_token: string;
        name: string;
    };
    userBankAccounts: {
        [bankId: string]: string[];
    };
}

ProviderUser

interface ProviderUser {
    displayName: string;
    tokens: AuthTokens[];
    scopes: string[];
}

interface AuthTokens {
    accessToken: string;
    refreshToken: string;
}

Database Setup

For each new user, the system: 1. Creates a dedicated Turso database 2. Generates an access token for the database 3. Stores database connection info in the user's Firestore record

Security Considerations

  • All authentication is handled through Firebase
  • Database access tokens are securely stored
  • Provider tokens are encrypted
  • Each user has isolated database access

API Endpoints

The signup flow primarily uses these endpoints:

  1. Firebase Authentication
  2. Handles OAuth flow
  3. Manages user sessions
  4. Provides JWT tokens

  5. Backend Authentication

  6. /api/v1/auth/verify - Token verification
  7. Internal user creation endpoints

Error Handling

The system handles various error scenarios:

  1. Authentication Failures
  2. Invalid tokens
  3. Expired sessions
  4. Provider errors

  5. Database Creation Failures

  6. Turso connection issues
  7. Duplicate user detection
  8. Storage failures

  9. Provider Integration Issues

  10. OAuth errors
  11. Token refresh failures
  12. Scope permission issues

Monitoring

The system logs key events: - User creation - Database initialization - Authentication attempts - Error conditions

Future Enhancements

Planned improvements: 1. Support for additional authentication providers 2. Enhanced error recovery 3. Improved monitoring and analytics 4. Additional security features

Areas for Improvement

By Category

1. Security Enhancements

  • Token Handling
  • Implement proper Authorization header validation
  • Add rate limiting for token verification attempts
  • Implement token revocation mechanism
  • Add token expiration checks
  • Remove sensitive data from debug logs

  • Database Security

  • Remove hardcoded development tokens
  • Implement encryption for sensitive data in Firestore
  • Add database access audit logging
  • Implement row-level security in Turso

  • Error Handling

  • Implement specific error types for different failure scenarios
  • Add proper error messages without exposing sensitive information
  • Implement consistent error handling patterns

2. Architecture Improvements

  • Clean Architecture
  • Create proper interfaces for authentication providers
  • Move Firebase Admin SDK dependency to infrastructure layer
  • Separate authentication and authorization concerns
  • Implement proper dependency injection

  • Repository Pattern

  • Define clear repository interfaces
  • Implement proper abstraction for data access
  • Separate concerns in AppUserRepository
  • Add proper transaction handling

  • Service Layer

  • Create provider-agnostic token management
  • Implement proper service interfaces
  • Add proper error handling in services
  • Implement proper validation

3. Code Quality

  • Error Handling
  • Standardize error handling patterns
  • Implement proper error types
  • Add proper error context
  • Implement proper error logging

  • Logging

  • Implement structured logging
  • Remove sensitive data from logs
  • Standardize log levels
  • Add proper log context

  • Type Safety

  • Add proper type hints
  • Implement proper validation
  • Use Pydantic models consistently
  • Add proper type checking

4. Performance

  • Database Operations
  • Implement caching strategy
  • Add proper batching for database operations
  • Implement pagination
  • Add proper indexing

  • Token Management

  • Implement token caching
  • Add proper token refresh mechanism
  • Implement proper token storage
  • Add proper token validation

By Priority

Critical (Security & Data Integrity)

  1. Remove hardcoded development tokens
  2. Implement proper Authorization header validation
  3. Add encryption for sensitive data in Firestore
  4. Implement proper error handling without sensitive data exposure
  5. Add proper token revocation mechanism

High (Architecture & Scalability)

  1. Create proper interfaces for authentication providers
  2. Implement proper repository interfaces
  3. Add proper transaction handling
  4. Implement proper caching strategy
  5. Add proper batching for database operations

Medium (Code Quality & Maintainability)

  1. Standardize error handling patterns
  2. Implement structured logging
  3. Add proper type hints
  4. Implement proper validation
  5. Add proper documentation

Low (Performance & Optimization)

  1. Implement token caching
  2. Add proper indexing
  3. Implement pagination
  4. Add proper batching
  5. Implement proper caching

Implementation Notes

Security Enhancements

# Example of improved token handling
def get_token_from_request(request: Request) -> str | None:
    auth_header = request.headers.get("Authorization")
    if not auth_header or not auth_header.startswith("Bearer "):
        return None
    return auth_header.split(" ")[1]

# Example of proper error handling
class AuthenticationError(Exception):
    pass

class TokenExpiredError(AuthenticationError):
    pass

@app.exception_handler(AuthenticationError)
async def auth_error_handler(request: Request, exc: AuthenticationError):
    return JSONResponse(
        status_code=401,
        content={"detail": str(exc)}
    )

Architecture Improvements

# Example of proper interface definition
class AuthProvider(ABC):
    @abstractmethod
    def verify_token(self, token: str) -> UserIdentity:
        pass

    @abstractmethod
    def refresh_token(self, refresh_token: str) -> TokenPair:
        pass

# Example of proper repository interface
class AppUserRepository(ABC):
    @abstractmethod
    def find_by_provider_id(self, provider_id: str, provider: str) -> AppUser | None:
        pass

    @abstractmethod
    def create(self, user: AppUser) -> None:
        pass

Performance Optimizations

# Example of caching implementation
class TokenCache:
    def __init__(self, redis_client: Redis):
        self.redis = redis_client

    async def get_token(self, key: str) -> str | None:
        return await self.redis.get(key)

    async def set_token(self, key: str, token: str, ttl: int):
        await self.redis.setex(key, ttl, token)

Each improvement should be tracked in the project's issue tracker and implemented with proper testing and documentation. The priority order should be adjusted based on specific project needs and security requirements.