Last Updated: February 25, 2026


Overview

This document provides detailed sequence diagrams for all authentication and user management flows in Herald. Each diagram shows the exact interactions between components.


1. User Login Flow (SSO)

Scenario

User visits a TC app (A, B, or C) without an active session and needs to log in.

Sequence Diagram

sequenceDiagram
    actor User
    participant App as TC App<br/>(todayscarolinian.com)
    participant Herald as Herald<br/>(herald.todayscarolinian.com)
    participant MW as Herald Middleware
    participant API as Auth Microservice API
    participant Firebase as Firebase Auth
    participant Firestore as Cloud Firestore
    participant Redis as Vercel KV<br/>(Rate Limiting)
    
    User->>App: Visit todayscarolinian.com/articles
    App->>App: Check for session cookie
    Note over App: No session cookie found
    App->>Herald: Redirect to /login?redirect=https://todayscarolinian.com/articles
    
    Herald->>User: Display login page
    User->>Herald: Submit email + password + rememberMe
    Herald->>API: POST /api/auth/login {email, password, rememberMe}
    
    API->>Redis: Check rate limit for email
    alt Rate limit exceeded
        Redis-->>API: Rate limit exceeded
        API-->>Herald: 429 Too Many Requests
        Herald-->>User: Show "Too many attempts" error
    else Within rate limit
        Redis-->>API: OK (increment counter)
        
        API->>Firebase: signInWithEmailAndPassword()
        alt Invalid credentials
            Firebase-->>API: Auth error
            API->>Redis: Increment failed attempts
            API-->>Herald: 401 Unauthorized
            Herald-->>User: Show "Invalid credentials" error
        else Valid credentials
            Firebase-->>API: Return ID token + user object
            
            API->>Firestore: Get user document /users/{uid}
            Firestore-->>API: User profile + position
            
            alt Email not verified
                API-->>Herald: 403 Email not verified
                Herald-->>User: Show "Please verify email" message
            else Must change password
                API->>API: Set session cookie
                API-->>Herald: 200 OK {mustChangePassword: true}
                Herald->>Herald: Redirect to /first-login
            else Normal login
                API->>Redis: Clear failed attempts counter
                API->>Firestore: Update lastLoginAt timestamp
                API->>Firestore: Create audit log: login_success
                API->>API: Set session cookie<br/>domain: .todayscarolinian.com<br/>maxAge: rememberMe ? 30d : 5d
                API-->>Herald: 200 OK {user, redirectUrl}
                Herald->>App: Redirect to original URL
                App->>App: Verify session cookie
                App->>Firestore: Fetch user profile (cached)
                App-->>User: Display authenticated page
            end
        end
    end

Key Points

  1. Rate Limiting: 5 failed attempts → 15 min lockout per email
  2. Session Cookie: Set with domain: .todayscarolinian.com for SSO
  3. Email Verification: Blocks login if email not verified
  4. Password Change: Forces redirect if mustChangePassword is true
  5. Audit Logging: Successful login creates audit log entry

2. First-Time Login (Force Password Change)

Scenario

Newly created user logs in with temporary password and must change it immediately.